Skip to content

docs: add warning about HTTP/3 and proxy incompatibility - #373

Merged
barjin merged 2 commits into
masterfrom
docs/http3-proxy-limitation
Feb 2, 2026
Merged

barjin merged 2 commits into
masterfrom
docs/http3-proxy-limitation

Conversation

@barjin

@barjin barjin commented Feb 1, 2026

Copy link
Copy Markdown
Member

Added warning to Python and Node.js documentation that proxies are not supported when HTTP/3 is enabled.

Closes #364

Proxies are not supported when HTTP/3 is enabled. This documents the
limitation in both Python and Node.js client options.

Closes #364

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
@github-actions github-actions Bot added this to the 133rd sprint - Tooling team milestone Feb 1, 2026
@github-actions github-actions Bot added the t-tooling Issues with this label are in the ownership of the tooling team. label Feb 1, 2026
@barjin
barjin merged commit 7fe603d into master Feb 2, 2026
47 of 48 checks passed
@barjin
barjin deleted the docs/http3-proxy-limitation branch February 2, 2026 07:47
barjin added a commit that referenced this pull request Oct 26, 2026
My agent got freaked by the weird http3 + proxy behavior. This is an
attempt to clean it up so it returns an error and doesn't silently
change behavior.

## AI Summary

HTTP/3 through a proxy isn't supported, and the docs say so. That was
decided in #246 and #364, documented in #373, and reqwest tracks it
upstream as seanmonstar/reqwest#2833. This PR doesn't try to add that
support. It makes the unsupported combination fail safe instead of
quietly sending traffic from the machine's own IP address.

The change only matters when **HTTP/3 is enabled and a proxy is set**,
whether through `with_proxy` / `proxyUrl` or through `HTTPS_PROXY` /
`ALL_PROXY`. Everything else behaves as before, including the default,
where HTTP/3 is off.

## What `master` does with HTTP/3 and a proxy

| Request | On `master` |
|---|---|
| `http3_prior_knowledge` | Every request goes straight to the target
over QUIC from the real IP. The proxy is never used. |
| Not forced, and the host advertises h3 in its DNS HTTPS record |
`H3Engine` looks the record up directly at `8.8.8.8`, which already
exposes the hostname from the real IP. The request then goes out over
QUIC from the real IP too. |
| Not forced, and the host advertises h3 only through `Alt-Svc` | The
first request goes through the proxy. impit then caches the host as
h3-capable, and every later request to it leaks. A quick one-request
test looks fine. |

None of these cases logs anything or returns an error.

I reproduced this on `master` with a local logging CONNECT proxy and
`https://www.google.com/`. The forced request never reached the proxy.
strace showed QUIC packets going directly to `142.251.153.119:443`, and
the DNS lookups going to `8.8.8.8` / `8.8.4.4`.

## With this PR

- When the client is built with a proxy, HTTP/3 is disabled and a
warning is logged. All traffic goes through the proxy over TCP (HTTP/2
or HTTP/1.1), and no lookups go directly to `8.8.8.8`.
- A request with `http3_prior_knowledge` fails with `Http3Disabled`,
whose message now mentions the proxy. It no longer goes out directly.
- A proxy that comes only from `HTTPS_PROXY` / `ALL_PROXY` is covered
too. On `master` it leaks the same way, and the docs don't mention it.

The PR also removes `.with_http3()` from the `ImpitBuilder` doc example,
which combined it with a proxy.

## Not changed

- HTTP/3 still can't go through a proxy. That's blocked in reqwest.
- `NO_PROXY` isn't considered. If any proxy is set, HTTP/3 is off for
all hosts. That's a deliberately conservative choice.
- I disable HTTP/3 rather than fail at build time, so existing `http3:
true` + proxy setups keep working over HTTP/2. That's easy to flip to an
error if you'd prefer.
- The unused QUIC endpoint that reqwest sets up whenever the `http3`
feature is compiled in is handled separately in #595.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_0148RYR4BTGyCYHENSRZjC3S

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jindřich Bär <jindrichbar@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(py) The Client and AsyncClient do not use a proxy if http3=True is set.

1 participant