cloudflare/quiche · error

malformed header provided

Error message

malformed header provided - "{header}"

What it means

with_urls parses custom request headers supplied as 'Name: value' strings, splitting on the first ': '. If a header string does not contain that separator exactly (splitn yields != 2 parts), the CLI panics. It is strict input validation of user-provided header text.

Solutions

  1. Format each header as 'Name: value' with a colon and a space after the name.
  2. Quote the header argument in your shell so spaces survive.
  3. Verify no leading/trailing whitespace corrupts the separator.

Example fix

// before
--header 'Host:example.com'
// after
--header 'Host: example.com'
Defensive patterns

Strategy: validation

Validate before calling

fn valid_header(h: &str) -> bool {
    match h.split_once(": ") { Some((k, v)) => !k.is_empty() && !v.is_empty(), None => false }
}
assert!(req_headers.iter().all(|h| valid_header(h)), "headers must be 'Name: value'");

Prevention

When it happens

Trigger: Passing --header values without the ': ' separator, e.g. 'Authorization=Bearer x', 'Host:example.com' (colon without following space), or an empty/whitespace header.

Common situations: Copy-pasting headers that use 'name:value' without a space, using '=' instead of ':', or forgetting the value entirely.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of cloudflare/quiche@9f96daa2c2 (2026-09-08). Data as JSON: /api/errors/78973844be9a9d24. Report an issue: GitHub.

Appendix: source

Thrown at apps/src/common.rs:814

                        b":path",
                        url[url::Position::BeforePath..].as_bytes(),
                    ),
                    quiche::h3::Header::new(b"user-agent", b"quiche"),
                ];

                let priority = if send_priority_update {
                    priority_from_query_string(url)
                } else {
                    None
                };

                // Add custom headers to the request.
                for header in req_headers {
                    let header_split: Vec<&str> =
                        header.splitn(2, ": ").collect();

                    if header_split.len() != 2 {
                        panic!("malformed header provided - \"{header}\"");
                    }

                    hdrs.push(quiche::h3::Header::new(
                        header_split[0].as_bytes(),
                        header_split[1].as_bytes(),
                    ));
                }

                if body.is_some() {
                    hdrs.push(quiche::h3::Header::new(
                        b"content-length",
                        body.as_ref().unwrap().len().to_string().as_bytes(),
                    ));
                }

                reqs.push(Http3Request {
                    url: url.clone(),
                    cardinal: i,

View on GitHub (pinned to 9f96daa2c2)