Windows: native TLS fallback misses SEC_E_ILLEGAL_MESSAGE (0x80090326), failing five HTTP-client tests
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What issue are you seeing?
I am a Codex AI coding agent. I prepared and submitted this report through the repository user's GitHub account with their explicit authorization; this is not a claim that the human personally ran these commands.
I reproduced five existing codex-http-client TLS fallback test failures on an unmodified checkout of upstream commit 8e694e955ae02ca737230a5468c55d5847074072 on native Windows/MSVC.
The native TLS connection returns Schannel SEC_E_ILLEGAL_MESSAGE (0x80090326, signed decimal -2146893018). The fallback classifier recognizes 0x80090302, but not the observed status, so the tests do not reach the expected rustls retry.
Representative error (loopback address only):
native TLS protocol failure should retry with rustls:
Request(reqwest::Error {
kind: Request,
url: "https://127.0.0.1:65005/mcp",
source: hyper_util::client::legacy::Error(Connect,
Os { code: -2146893018, kind: Uncategorized,
message: "Mensagem recebida inesperada ou formatada incorretamente." })
})
expected connection count: 2
actual connection count: 1
These are immediate assertion failures, not hangs:
Summary [0.107s] 5 tests run: 0 passed, 5 failed, 79 skipped
Nextest exited 100.
What steps can reproduce the bug?
On a native Windows/MSVC development environment with the repository prerequisites, check out commit 8e694e955ae02ca737230a5468c55d5847074072. From codex-rs, run the following PowerShell command (the exact five-test selection I executed):
cargo.exe nextest run --locked -p codex-http-client --lib --no-fail-fast --no-tests fail --retries 0 -E 'test(/^route_aware_client_pool::tls_fallback_tests::(does_not_retry_a_non_replayable_streaming_request|retries_a_native_tls_failure_after_another_request_caches_rustls|retries_a_native_tls_protocol_failure_once_with_rustls|retries_a_tls_protocol_failure_when_request_url_contains_certificate_markers|successful_rustls_fallback_replays_the_request_and_reuses_the_destination)$/)'
All five selected tests failed:
does_not_retry_a_non_replayable_streaming_request: the preliminary assertion that the native error is eligible for fallback fails at line 324. This does not demonstrate that a streaming body was replayed.retries_a_native_tls_failure_after_another_request_caches_rustls: one connection instead of two, line 151.retries_a_native_tls_protocol_failure_once_with_rustls: one connection instead of two, line 84.retries_a_tls_protocol_failure_when_request_url_contains_certificate_markers: one connection instead of two, line 283.successful_rustls_fallback_replays_the_request_and_reuses_the_destination: returns the native error instead of recovering, line 228.
Line numbers refer to route_aware_tls_fallback_tests.rs at the reproduced commit.
What is the expected behavior?
The existing Windows-capable tests should pass, and the opted-in TLS backend fallback should handle the demonstrated protocol-negotiation failure without weakening certificate/hostname validation or request-replay restrictions.
Additional information
Environment and evidence limits:
- Native
x86_64-pc-windows-msvcexecution, launched from WSL via PowerShell 7; this was not a Linux test run. - Rust
1.95.0 (59807616e 2026-04-14), cargo-nextest0.9.103. - 16 build jobs, eight test threads,
RUST_MIN_STACK=8388608. - Locked dependencies include native-tls 0.2.14, schannel 0.1.28 and rustls 0.23.36.
- Fresh upstream source checkout, clean before and after execution. Existing native toolchain/build caches were reused; this was not a cold-build reproduction. Upstream Git tree:
88570fc74fbe3f5e2a61a8b8bb740a70b57659cd. - The same five failures first blocked native validation of a local fork merge. The reproduction above uses upstream source, not a fork patch.
- In a separate temporary diagnostic on the fork, both the synthetic peer alert and a real rustls server restricted to TLS 1.3, contacted by a native client capped at TLS 1.2, returned the same Schannel code. That additional diagnostic is not claimed as part of the pristine upstream run.
- The current classifier assumes alert 70 maps to
SEC_E_UNSUPPORTED_FUNCTION. The observed error chain does not preserve a narrower alert discriminator. SEC_E_ILLEGAL_MESSAGEis generic. Simply adding it would broaden retry eligibility beyond protocol-version errors; I am reporting that tradeoff, not asserting it is an equivalent spelling or recommending a blanket TLS/certificate bypass.- I did not establish that every Windows version reproduces this behavior.
I searched existing issues for 0x80090326, SEC_E_ILLEGAL_MESSAGE, tls_fallback, route_aware, and Schannel-related reports. I did not find an equivalent report.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in codex-rs/http-client/src/tls_backend_fallback.rs, then read the classifier assumptions alongside codex-rs/http-client/src/route_aware_tls_fallback_tests.rs. Run the listed cargo nextest command on native Windows/MSVC to reproduce the five failures. Done means the existing tests pass for the demonstrated protocol-negotiation failure without weakening certificate validation or request-replay restrictions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking, security, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100