`codex exec`/app-server fails with "failed to lookup address information: Try again" behind DNS middleboxes that answer `AAAA` with `REFUSED` — same environment works for curl/glibc tools

Open 💬 1 comment Opened Jul 7, 2026 by arjmandi

Environment

  • codex-cli 0.137.0-alpha.4 (bundled openai-codex-cli-bin 0.137.0a4 /

openai-codex 0.1.0b3 Python SDK) — Linux x86_64 binary is
static-PIE (musl) per file(1)

  • Guest: Debian trixie userland (glibc 2.41), Linux 6.12, inside a

microsandbox microVM whose DNS is a userspace interceptor

  • Auth: OPENAI_API_KEY (ApiKey mode)

Summary

The VM's DNS resolver has a real bug: for a name that has A records but no
AAAA
(api.openai.com), it answers the AAAA query with REFUSED
(rcode 5)
instead of NOERROR+empty (NODATA). We've reported that separately to microsandbox: https://github.com/superradcompany/microsandbox/issues/1139

However, the impact asymmetry is worth a look on codex's side:

  • glibc-linked tools tolerate it: curl, getent, Python — and the

Anthropic/deepagents agents we run beside codex — all resolve
api.openai.com instantly (they use the A records; sequential and
40-thread-concurrent getaddrinfo loops: 0 failures in 200+ lookups).

  • codex hard-fails: every turn dies after ~5 s with

stream disconnected before completion: failed to lookup address
information: Try again
(wss:// first, then the HTTPS fallback), attempt
after attempt — the codex agent is unusable in this environment while
every other HTTP client on the box works.

RUST_LOG=debug shows the request never reaches TCP connect for
api.openai.com (no connecting to <ip>:443 after
reqwest::connect: starting new connection), while ab.chatgpt.com (which
HAS AAAA records, so no REFUSED is emitted) resolves and connects in ~3 ms
from the same process.

Since the Linux binary is statically linked (musl), codex doesn't get glibc's
lenient behavior of "use the A answer if the AAAA leg errors"; the resolver
in the static build appears to treat the REFUSED AAAA response as fatal for
the whole lookup (and retries against a secondary nameserver that may be
unreachable, burning the ~5 s budget).

Reproduction

Easiest faithful repro is a stub resolver that mimics the middlebox: answer
A normally, answer AAAA for the target name with rcode 5.

  1. Run a local DNS proxy on 127.0.0.53 that forwards everything but rewrites

the AAAA api.openai.com response to REFUSED (a ~30-line Python UDP
proxy does it; happy to attach ours).

  1. Point /etc/resolv.conf at it.
  2. curl https://api.openai.com/v1/models → fast 401 (works).
  3. OPENAI_API_KEY=… codex exec 'reply with: ok'

failed to lookup address information: Try again after ~5 s, all retries.

Observed in the wild inside microsandbox VMs (their DNS interceptor behaves
exactly like the stub above).

Expected

codex's resolution should be no stricter than getaddrinfo(3) in practice: if
the A query succeeds, a failed/REFUSED AAAA leg should degrade to
IPv4-only resolution (arguably RFC 6555/8305 spirit), not fail the lookup —
matching what every glibc-linked client on the same host does.

Workaround (for anyone hitting this)

Pin the host's A records in /etc/hosts (codex consults it before
querying):

for ip in $(getent ahostsv4 api.openai.com | awk '{print $1}' | sort -u); do
  echo "$ip api.openai.com" >> /etc/hosts
done

This restored codex end-to-end for us (thread.run → status=completed).

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗