ducaale/xh · error

HTTP/3 is not supported when using native-tls

Error message

HTTP/3 is not supported when using native-tls

What it means

Runtime configuration check in run (the request setup path, called from main): the user selected HTTP/3 prior-knowledge (HttpVersion::Http3PriorKnowledge) while the binary was compiled against native-tls for TLS, a backend that reqwest does not allow to be combined with HTTP/3. Client construction is aborted before any request is sent; the fix is to use a rustls-based build or choose a different HTTP version.

Solutions

  1. Drop the --native-tls flag when using HTTP/3 (rustls is required).
  2. Use a lower HTTP version (e.g. --http2) if native-tls is mandatory for your environment.
  3. Remove the explicit HTTP/3 version option and let negotiation pick a supported version.
  4. If you need both, use a build where HTTP/3 works and keep default TLS.

Example fix

// before
xh --http3 --native-tls GET example.org
// after
xh --http3 GET example.org
Defensive patterns

Strategy: validation

Validate before calling

// guard before invocation
if http3_requested && native_tls_flag { echo "HTTP/3 requires rustls; drop --native-tls" >&2; exit 2; }

Try / catch

match run(args) {
    Err(e) if e.to_string().contains("HTTP/3 is not supported when using native-tls") => {
        args.native_tls = false;
        run(args)
    }
    other => other,
}

Prevention

When it happens

Trigger: run() handles Some(HttpVersion::Http3PriorKnowledge) with the http3 feature enabled and args.native_tls == true.

Common situations: Combining --http3 (or http_version=http3) with --native-tls on the same invocation; scripts that hardcode both flags for different hosts; misunderstanding that HTTP/3 requires QUIC TLS which native-tls does not provide.

Understand the failure class

Related errors


AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13). Data as JSON: /api/errors/91217146d9b23a54. Report an issue: GitHub.

Appendix: source

Thrown at src/main.rs:294

    }

    for proxy in args.proxy.into_iter().rev() {
        client = client.proxy(match proxy {
            Proxy::Http(url) => reqwest::Proxy::http(url),
            Proxy::Https(url) => reqwest::Proxy::https(url),
            Proxy::All(url) => reqwest::Proxy::all(url),
        }?);
    }

    client = match args.http_version {
        Some(HttpVersion::Http10 | HttpVersion::Http11) => client.http1_only(),
        Some(HttpVersion::Http2PriorKnowledge) => client.http2_prior_knowledge(),
        Some(HttpVersion::Http2) => client,
        Some(HttpVersion::Http3PriorKnowledge) => {
            #[cfg(feature = "http3")]
            {
                if args.native_tls {
                    return Err(anyhow!("HTTP/3 is not supported when using native-tls"));
                }
                client.http3_prior_knowledge()
            }
            #[cfg(not(feature = "http3"))]
            {
                return Err(anyhow!(
                    "This binary was built without support for HTTP/3. Enable the `http3` feature."
                ));
            }
        }
        None => client,
    };

    let cookie_jar = Arc::new(reqwest_cookie_store::CookieStoreMutex::default());
    client = client.cookie_provider(cookie_jar.clone());

    client = match (args.ipv4, args.ipv6) {
        (true, false) => client.local_address(IpAddr::from(Ipv4Addr::UNSPECIFIED)),

View on GitHub (pinned to 2404aceecc)