Skip to content

hyper creates bad request on Intel mac for opt-level > 0 #3902

@mkenigs

Description

@mkenigs

Version
hyper 1.6.0
cargo 1.87.0 (99624be96 2025-05-06)

Platform
Darwin XXX 23.5.0 Darwin Kernel Version 23.5.0: Wed May 1 20:09:52 PDT 2024; root:xnu-10063.121.3~5/RELEASE_X86_64 x86_64 i386 Darwin

Description

TLDR: it seems for a specific compiler combination (cargo 1.87.0, Intel mac, build with opt-level > 0), HTTP/1.1 is not being added to an http request.

Reproducer:
Cargo.toml:

[package]
name = "reproducer"
version = "0.1.0"
edition = "2024"

[dependencies]
reqwest = { version = "0.12", features = ["json", "blocking", "stream"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing = "0.1"

src/main.rs:

use tracing_subscriber::EnvFilter;

fn main() {
    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .init();

    let client = reqwest::blocking::ClientBuilder::new()
        .connection_verbose(true)
        .build()
        .unwrap();

    client.get("https://example.com").send().unwrap();
}

Building and running gets a 400 returned:

$ cargo build --profile release
$ RUST_LOG=trace ./target/release/reproducer
2025-06-09T19:47:03.286067Z TRACE reqwest::blocking::wait: (ThreadId(1)) park without timeout
2025-06-09T19:47:03.286159Z TRACE reqwest::blocking::client: (ThreadId(2)) start runtime::block_on
2025-06-09T19:47:03.290429Z TRACE reqwest::blocking::wait: wait at most 30s
2025-06-09T19:47:03.290449Z TRACE reqwest::blocking::wait: (ThreadId(1)) park timeout 29.999993742s
2025-06-09T19:47:03.290504Z TRACE hyper_util::client::legacy::pool: checkout waiting for idle connection: ("https", example.com)
2025-06-09T19:47:03.290530Z DEBUG reqwest::connect: starting new connection: https://example.com/
2025-06-09T19:47:03.290551Z TRACE hyper_util::client::legacy::connect::http: Http::connect; scheme=Some("https"), host=Some("example.com"), port=None
2025-06-09T19:47:03.292339Z DEBUG hyper_util::client::legacy::connect::http: connecting to 23.192.228.84:443
2025-06-09T19:47:03.349905Z DEBUG hyper_util::client::legacy::connect::http: connected to 23.192.228.84:443
2025-06-09T19:47:03.485929Z TRACE hyper_util::client::legacy::client: http1 handshake complete, spawning background dispatcher task
2025-06-09T19:47:03.485947Z TRACE hyper_util::client::legacy::client: waiting for connection to be ready
2025-06-09T19:47:03.485985Z TRACE hyper_util::client::legacy::client: connection is ready
2025-06-09T19:47:03.486000Z TRACE hyper_util::client::legacy::pool: checkout dropped for ("https", example.com)
2025-06-09T19:47:03.486087Z TRACE reqwest::connect::verbose: 50994943 write: b"GET / \r\naccept: */*\r\nhost: example.com\r\n\r\n"
2025-06-09T19:47:03.543999Z TRACE reqwest::connect::verbose: 50994943 read: b"HTTP/1.0 400 Bad Request\r\nServer: AkamaiGHost\r\nMime-Version: 1.0\r\nContent-Type: text/html\r\nContent-Length: 312\r\nExpires: Mon, 09 Jun 2025 19:47:03 GMT\r\nDate: Mon, 09 Jun 2025 19:47:03 GMT\r\nConnection: close\r\n\r\n<HTML><HEAD>\n<TITLE>Bad Request</TITLE>\n</HEAD><BODY>\n<H1>Bad Request</H1>\nYour browser sent a request that this server could not understand.<P>\nReference&#32;&#35;7&#46;4ea33017&#46;1749498423&#46;0\n<P>https&#58;&#47;&#47;errors&#46;edgesuite&#46;net&#47;7&#46;4ea33017&#46;1749498423&#46;0</P>\n</BODY>\n</HTML>\n"
2025-06-09T19:47:03.544385Z TRACE reqwest::blocking::client: closing runtime thread (ThreadId(2))
2025-06-09T19:47:03.544409Z TRACE reqwest::blocking::client: signaled close for runtime thread (ThreadId(2))
2025-06-09T19:47:03.544431Z TRACE reqwest::blocking::client: (ThreadId(2)) Receiver is shutdown
2025-06-09T19:47:03.544457Z TRACE reqwest::blocking::client: (ThreadId(2)) end runtime::block_on
2025-06-09T19:47:03.544584Z TRACE reqwest::blocking::client: (ThreadId(2)) finished
2025-06-09T19:47:03.544727Z TRACE reqwest::blocking::client: closed runtime thread (ThreadId(2))

Note this line of output:

2025-06-09T19:47:03.486087Z TRACE reqwest::connect::verbose: 50994943 write: b"GET / \r\naccept: */*\r\nhost: example.com\r\n\r\n"

If I add these lines to Cargo.toml:

[profile.release.package."hyper"]
opt-level = 0

I get a 200 instead of a 400, and I notice this line of output:

2025-06-09T19:50:17.046408Z TRACE reqwest::connect::verbose: 6fa1e4b0 write: b"GET / HTTP/1.1\r\naccept: */*\r\nhost: example.com\r\n\r\n"

In the successful request, there's an HTTP/1.1 after GET, but that's not present for the request that returns 400.

Additionally:

  • I only see this on an Intel mac, not one with Apple silicon
  • I only see this with cargo 1.87.0, not with 1.85.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: bug. Something is wrong. This is bad!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions