Client or integration
Codex App
Area
Proxy and routing
Summary
On machines using Clash / Surge / Mihomo fake-IP DNS, provider model discovery still fails with blocked by destination policy: ... resolves to non-global address, even though #1748 added the fake-IP allowance.
The root cause is that the fake-IP opt-in in resolvePublicAddresses() is unreachable for IPv6-mapped answers. classifyIpv6() decodes hex IPv4-mapped IPv6 with:
const hexMapped = hostname.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
That pattern assumes exactly two hex groups (::ffff:c612:1b). But the resolver here returns an explicit zero group:
cli-chat-proxy.grok.com has address 198.18.0.27
cli-chat-proxy.grok.com has IPv6 address ::ffff:0:c612:1b
::ffff:0:c612:1b does not match, so it falls through to the generic tail:
return { kind: "private", detail: "non-global address" };
It is therefore classified private with detail "non-global address" — not "benchmark address". The allowance in resolvePublicAddresses() is gated on that exact detail string:
if (benchmarkAllowed && assessment?.kind === "private" && assessment.detail === "benchmark address") {
so the branch never runs, and the request is rejected regardless of HTTP(S)_PROXY being correctly configured. Node's ipaddress-style parsers agree the address is not a canonical ipv4_mapped value, which is why it reaches the hex path at all.
Security note: this same gap means loopback/private/link-local addresses in that zero-group form also skip IPv4 classification today. See the table below — fixing the regex tightens the policy rather than loosening it.
Reproduction
- Run Clash / Surge / Mihomo with fake-IP DNS enabled (
198.18.0.0/15).
- Export a working proxy, e.g.
export HTTPS_PROXY=http://127.0.0.1:1082.
- Configure any provider whose hostname resolves through fake-IP (reproduced with
xai, but it affects every provider on this machine).
ocx restart then ocx provider test xai.
Observed:
xai: failed
upstream /models blocked by destination policy: provider URL hostname cli-chat-proxy.grok.com resolves to non-global address (::ffff:0:c612:1b)
Expected: discovery succeeds by riding the configured proxy as an ordinary hostname CONNECT, per #1748.
Note the destination is reachable — the block is purely the classification:
curl -x http://127.0.0.1:1082 https://cli-chat-proxy.grok.com/v1/models -> 401 (expected unauthenticated response)
Inference through the proxy also works fine; only discovery is blocked, so the failure is masked by the configured-model fallback.
Suggested fix
Make the zero group optional in src/lib/destination-policy.ts:
- const hexMapped = hostname.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
+ const hexMapped = hostname.match(/^::ffff:(?:0{1,4}:)?([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
Verified locally against v2.33.0. Decoding behaviour before/after:
| Input |
old |
new |
decoded |
intent |
::ffff:0:c612:1b |
miss |
hit |
198.18.0.27 |
fake-IP → allow via proxy |
::ffff:c612:1b |
hit |
hit |
198.18.0.27 |
unchanged |
::ffff:0:7f00:1 |
miss |
hit |
127.0.0.1 |
now correctly blocked |
::ffff:0:c0a8:1 |
miss |
hit |
192.168.0.1 |
now correctly blocked |
::ffff:0:a9fe:a9fe |
miss |
hit |
169.254.169.254 |
now correctly blocked |
::ffff:0:0:c612:1b |
miss |
miss |
— |
4 groups still rejected |
After applying it, all seven configured providers recovered live discovery, and the seven blocked by destination policy warnings disappeared from ocx sync:
| Provider |
before |
after |
| xai |
blocked |
connected — 2 models |
| anthropic |
blocked |
connected — 10 models |
| kimi |
blocked |
connected — 4 models |
| deepseek |
blocked |
connected — 3 models |
| minimax-cn |
blocked |
connected — 8 models |
| zhipu-bigmodel-coding |
blocked |
connected — 10 models |
| google-antigravity |
blocked |
connected — 6 models |
Happy to send this as a PR with a regression test over the address matrix above if useful.
Version
2.33.0
Operating system
macOS 26.5.2 (arm64)
Provider and model
xai / grok-4.6 (reproduces on all configured providers)
Logs or error output
$ ocx sync
[opencodex] Provider model discovery for "minimax-cn" was blocked by destination policy: provider URL hostname api.minimaxi.com resolves to non-global address (::ffff:0:c612:24) [urlClass=provider-models, fallback=configured].
[opencodex] Provider model discovery for "xai" was blocked by destination policy: provider URL hostname cli-chat-proxy.grok.com resolves to non-global address (::ffff:0:c612:1b) [urlClass=provider-models, fallback=configured].
[opencodex] Provider model discovery for "google-antigravity" was blocked by destination policy: provider URL hostname daily-cloudcode-pa.googleapis.com resolves to non-global address (::ffff:0:c612:29) [urlClass=provider-models, fallback=configured].
[opencodex] Provider model discovery for "anthropic" was blocked by destination policy: provider URL hostname api.anthropic.com resolves to non-global address (::ffff:0:c612:28) [urlClass=provider-models, fallback=configured].
[opencodex] Provider model discovery for "zhipu-bigmodel-coding" was blocked by destination policy: provider URL hostname open.bigmodel.cn resolves to non-global address (::ffff:0:c612:26) [urlClass=provider-models, fallback=configured].
[opencodex] Provider model discovery for "deepseek" was blocked by destination policy: provider URL hostname api.deepseek.com resolves to non-global address (::ffff:0:c612:25) [urlClass=provider-models, fallback=configured].
[opencodex] Provider model discovery for "kimi" was blocked by destination policy: provider URL hostname api.kimi.com resolves to non-global address (::ffff:0:c612:27) [urlClass=provider-models, fallback=configured].
$ ocx sync # after the one-line fix
[opencodex] Provider outbound proxy mode preserves Bun proxy/NO_PROXY routing and validates the URL plus available local DNS results.
+ 18 models appended to Codex catalog
Checks
Client or integration
Codex App
Area
Proxy and routing
Summary
On machines using Clash / Surge / Mihomo fake-IP DNS, provider model discovery still fails with
blocked by destination policy: ... resolves to non-global address, even though #1748 added the fake-IP allowance.The root cause is that the fake-IP opt-in in
resolvePublicAddresses()is unreachable for IPv6-mapped answers.classifyIpv6()decodes hex IPv4-mapped IPv6 with:That pattern assumes exactly two hex groups (
::ffff:c612:1b). But the resolver here returns an explicit zero group:::ffff:0:c612:1bdoes not match, so it falls through to the generic tail:It is therefore classified
privatewith detail"non-global address"— not"benchmark address". The allowance inresolvePublicAddresses()is gated on that exact detail string:so the branch never runs, and the request is rejected regardless of
HTTP(S)_PROXYbeing correctly configured. Node'sipaddress-style parsers agree the address is not a canonicalipv4_mappedvalue, which is why it reaches the hex path at all.Security note: this same gap means loopback/private/link-local addresses in that zero-group form also skip IPv4 classification today. See the table below — fixing the regex tightens the policy rather than loosening it.
Reproduction
198.18.0.0/15).export HTTPS_PROXY=http://127.0.0.1:1082.xai, but it affects every provider on this machine).ocx restartthenocx provider test xai.Observed:
Expected: discovery succeeds by riding the configured proxy as an ordinary hostname
CONNECT, per #1748.Note the destination is reachable — the block is purely the classification:
Inference through the proxy also works fine; only discovery is blocked, so the failure is masked by the configured-model fallback.
Suggested fix
Make the zero group optional in
src/lib/destination-policy.ts:Verified locally against v2.33.0. Decoding behaviour before/after:
::ffff:0:c612:1b::ffff:c612:1b::ffff:0:7f00:1::ffff:0:c0a8:1::ffff:0:a9fe:a9fe::ffff:0:0:c612:1bAfter applying it, all seven configured providers recovered live discovery, and the seven
blocked by destination policywarnings disappeared fromocx sync:Happy to send this as a PR with a regression test over the address matrix above if useful.
Version
2.33.0
Operating system
macOS 26.5.2 (arm64)
Provider and model
xai / grok-4.6 (reproduces on all configured providers)
Logs or error output
Checks