seanmonstar/warp · error

illegal Header

Error message

illegal Header

What it means

The `allow_header` builder converts the given value into `http::HeaderName` and panics with "illegal Header" if conversion fails. Header names must be valid lowercase ASCII tokens; the builder panics rather than returning a Result because it is intended for statically valid configuration.

Solutions

  1. Pre-validate with `http::header::HeaderName::try_from(s)` (or `.parse::<HeaderName>()`) before calling `allow_header`.
  2. Pass `http::header::constants` directly (e.g. `http::header::AUTHORIZATION`, `http::header::CONTENT_TYPE`) to avoid conversion failures.
  3. Clean the configured values: use the bare header name only, trimmed, ASCII, no colons or values.
  4. Fail at config-load time with a descriptive error if any header name is invalid.

Example fix

// before
let cors = warp::cors().allow_header(cfg.header); // "Content Type" -> panic

// after
let name: http::HeaderName = cfg
    .header
    .parse()
    .map_err(|e| anyhow!("invalid CORS header name '{}': {}", cfg.header, e))?;
let cors = warp::cors().allow_header(name);
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_header(s: &str) -> bool {
    http::header::HeaderName::try_from(s).is_ok()
}
// before calling: assert!(is_valid_header(cfg.header));

Type guard

fn as_header(s: &str) -> Option<http::header::HeaderName> {
    http::header::HeaderName::try_from(s).ok()
}

Try / catch

// validate instead of catching the panic:
let name = http::header::HeaderName::try_from(input.as_str())
    .map_err(|e| format!("invalid CORS header '{}': {}", input, e))?;
let cors = warp::cors().allow_header(name);

Prevention

When it happens

Trigger: Calling `warp::cors().allow_header(h)` where `h` cannot convert to `HeaderName` — e.g. `allow_header("Content Type")` (space), `allow_header("")`, names with non-ASCII or illegal characters, or strings that fail `HeaderName` validation.

Common situations: Header names copied from HTTP logs with whitespace or values attached ("Authorization: Bearer"), config files listing headers with typos, passing header values instead of names, mixed-case is fine but special characters are not.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of seanmonstar/warp@ff34d7213e (2026-09-09). Data as JSON: /api/errors/b9dcd5ac844657e3. Report an issue: GitHub.

Appendix: source

Thrown at src/filters/cors.rs:128

        });
        self.methods.extend(iter);
        self
    }

    /// Adds a header to the list of allowed request headers.
    ///
    /// **Note**: These should match the values the browser sends via `Access-Control-Request-Headers`, e.g. `content-type`.
    ///
    /// # Panics
    ///
    /// Panics if the provided argument is not a valid `http::header::HeaderName`.
    pub fn allow_header<H>(mut self, header: H) -> Self
    where
        HeaderName: TryFrom<H>,
    {
        let header = match TryFrom::try_from(header) {
            Ok(m) => m,
            Err(_) => panic!("illegal Header"),
        };
        self.allowed_headers.insert(header);
        self
    }

    /// Adds multiple headers to the list of allowed request headers.
    ///
    /// **Note**: These should match the values the browser sends via `Access-Control-Request-Headers`, e.g.`content-type`.
    ///
    /// # Panics
    ///
    /// Panics if any of the headers are not a valid `http::header::HeaderName`.
    pub fn allow_headers<I>(mut self, headers: I) -> Self
    where
        I: IntoIterator,
        HeaderName: TryFrom<I::Item>,
    {
        let iter = headers.into_iter().map(|h| match TryFrom::try_from(h) {

View on GitHub (pinned to ff34d7213e)