Repository navigation
Description
Client or integration
Codex App
Area
Provider adapter
Summary
Requests using a GitHub Copilot-backed model intermittently fail with HTTP 502. The OpenCodex proxy reports ERR_TLS_CERT_ALTNAME_INVALID while fetching the GitHub Copilot API. I expected the request to complete successfully or return a provider-level error, not a TLS certificate hostname mismatch.
Reproduction
- Run OpenCodex locally on port 10100.
- Configure the Codex App to use the OpenAI-compatible endpoint http://127.0.0.1:10100/v1.
- Select the GitHub Copilot-backed model github-copilot/claude-sonnet-4.
- Send a normal chat/request.
- The request fails with HTTP 502.
Observed error:
unexpected status 502 Bad Gateway: Provider unreachable: ERR_TLS_CERT_ALTNAME_INVALID fetching https://api.individual.githubcopilot.com/chat/completions. For more information, pass verbose: true in the second argument to fetch(), url: http://127.0.0.1:10100/v1/responses
The failure appears to occur in the provider adapter when translating /v1/responses to the Copilot Chat Completions endpoint.
Version
2.7.41
Operating system
macOS 26.5.1 (Build 25F80), Apple Silicon
Provider and model
github-copilot/claude-sonnet-4
Logs or error output
unexpected status 502 Bad Gateway: Provider unreachable: ERR_TLS_CERT_ALTNAME_INVALID fetching https://api.individual.githubcopilot.com/chat/completions. For more information, pass verbose: true in the second argument to fetch(), url: http://127.0.0.1:10100/v1/responsesScreenshots and supporting files
No response
Redacted configuration
[proxy]
base_url = http://127.0.0.1:10100/v1
provider = GitHub Copilot
model = github-copilot/claude-sonnet-4
No credentials or tokens included.Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
github-actions commentedon Jul 27, 2026
Automated translation bookkeeping — detected language: unknown.
Ingwannu commentedon Jul 27, 2026
I checked the exact reported hostname and current
devtransport path. OpenCodex accepts the OAuth token's allowlisted*.githubcopilot.comAPI endpoint, sohttps://api.individual.githubcopilot.com/chat/completionsis an expected Copilot endpoint rather than a malformed URL.I cannot reproduce the TLS failure now:
api.individual.githubcopilot.comcurrently resolves to140.82.112.21here.*.individual.githubcopilot.comandindividual.githubcopilot.com.api.githubcopilot.comandapi.individual.githubcopilot.comwithout a hostname error.That makes a deterministic adapter URL bug unlikely. The remaining possibilities are a transient upstream certificate rollout, local/VPN/custom-DNS/antivirus TLS interception, or a resolver-specific endpoint.
Please capture the following on the affected Mac immediately after a failure (no tokens are involved):
Also include the failure timestamp/time zone and whether a VPN, proxy, custom DNS, or HTTPS-inspecting security product is active. If curl shows the wrong certificate too, this is outside the adapter; if curl is clean while OpenCodex fails at the same moment, we can isolate the Bun connection path. Marking
needs-infoand leaving it open rather than changing TLS validation or disabling certificate checks.burhiepotdult1982 commentedon Jul 28, 2026
I reproduced the TLS hostname mismatch on the affected Mac and captured the requested output. Shadowrocket TUN and the company Yunshu/VPN were active during the test. No tokens or credentials were included.
During the failing run:
I then repeated the same test at 2026-07-28 01:40 GMT+8. The result was different:
This confirms an intermittent local TUN/VPN/DNS or routing/certificate-interception problem rather than a deterministic malformed Copilot URL. The successful retest also shows that the current path can serve the correct Copilot certificate. I will continue with an actual POST request through OpenCodex if needed. The exact wall-clock timestamp of the first failing run was not recorded.
docs(devlog): roadmap lock for the bug-label resolution unit
lidge-jun commentedon Jul 28, 2026
Status: PR #575 improves attribution, but does not resolve the TLS mismatch
To set expectations correctly on what is in flight here.
PR #575 is open and mergeable. It makes the proxy distinguish a TLS hostname mismatch from an unreachable provider, so
ERR_TLS_CERT_ALTNAME_INVALIDstops being reported as a generic upstream failure and carries a recovery hint instead.That changes what you are told, not what happens. The underlying condition in your capture —
api.individual.githubcopilot.comresolving to198.18.0.17while Shadowrocket TUN and the corporate VPN were active, so the presented certificate does not cover the requested hostname — is an interception/routing condition outside the proxy. Merging #575 will not make that request succeed, and this issue should not be closed by it.Keeping this open for that reason. If you can retest with the TUN and VPN disabled and confirm the same request succeeds, that would confirm the split cleanly and tell us whether anything remains on our side beyond the error message.
fix(responses): tell TLS hostname mismatches apart from an unreachabl…
lidge-jun commentedon Jul 29, 2026
Status update: #575 is merged (
fff8c369f), and as stated earlier it does not close this issue.What changed is the diagnosis you get. The proxy now separates a TLS certificate/hostname mismatch from an unreachable provider, so instead of
you get a message that names the host, states that opencodex did not rewrite it, and gives the command that settles which certificate is actually being served. That removes the misreading this issue was originally filed on — that the adapter was mangling the Copilot URL. It was not:
*.githubcopilot.comis an allow-listed Copilot endpoint.What has not changed is your actual failure. In your capture
api.individual.githubcopilot.comresolved to198.18.0.17with Shadowrocket TUN and the corporate VPN active, so the presented certificate does not cover the requested hostname. That is an interception/routing condition ahead of the proxy, and no proxy-side change makes that request succeed.So this stays open on the original ask. The retest that would settle it is unchanged: with TUN and the VPN disabled, confirm the same request succeeds. If it does, this closes as environmental. If it still fails with the certificate mismatch on a clean network path, that would be new information and worth digging into.
One incidental note, since it touched the same code path: the old message echoed the fetched URL verbatim, and a provider base URL can carry credentials as
https://user:token@host/. Both branches now redact userinfo, so an error string can no longer hand back a token. Not your report, but it was found while rewriting this message and is worth knowing if you have ever pasted an error containing a base URL.lidge-jun commentedon Aug 2, 2026
Triage status: the evidence so far points at local VPN/fake-IP interception (Shadowrocket-class) rather than the proxy — #575 already fixed the attribution side. Could you retest on a clean network (VPN fully disabled)? If it still fails there, please capture the TLS handshake hostname from the failing request and we will reopen the investigation.
lidge-jun commentedon Aug 2, 2026
Triage: the proxy now classifies TLS-interception-shaped connect failures explicitly (src/server/responses/upstream-error.ts:18, tests/upstream-connect-error.test.ts), but the reported VPN/fake-IP certificate mismatch itself is environmental and cannot be prevented proxy-side. Leaving open for the documentation/improved-guidance track.
lidge-jun commentedon Aug 3, 2026
Closing this as an environment fault rather than an opencodex defect, on the evidence you supplied yourself.
Your own diagnostics showed a Shadowrocket fake-IP DNS route returning a NetEase certificate for the Copilot hostname, and a later route returning the correct Copilot certificate. That is TLS interception on the path, not a hostname rewrite in the adapter. The Copilot transport accepts only HTTPS
*.githubcopilot.comendpoints (src/providers/github-copilot-transport.ts:43) and deliberately does not relax certificate verification to accommodate an intercepting proxy — doing so would silently accept a man-in-the-middle for every user.What did change since you filed: PR #575 (
fff8c369f) added TLS-interception identification with an SNI probe atsrc/server/responses/upstream-error.ts:18-25, so the same failure now reports what it actually is instead of surfacing as a bare 502. That fixed the diagnosis, not the connection — and the connection was never ours to fix.If you hit
ERR_TLS_CERT_ALTNAME_INVALIDagain on a route where you are not running an intercepting proxy, please reopen with the certificate subject from the probe output. That would be a different problem and worth tracking.Thanks for the certificate captures — they made this unambiguous.
docs(devlog): roadmap lock for the bug-label resolution unit
fix(responses): tell TLS hostname mismatches apart from an unreachabl…