actix/actix-web · critical

Invalid header name

Error message

Invalid header name

What it means

The deprecated `DefaultHeaders::header()` helper at actix-web/src/middleware/default_headers.rs:88-95 converts the key with `HeaderName::try_from` and `.expect("Invalid header name")` on failure. Any byte sequence that is not a valid HTTP header token (e.g. contains `:`, spaces, or non-token characters) panics.

Source

Thrown at actix-web/src/middleware/default_headers.rs:91

        self
    }

    #[doc(hidden)]
    #[deprecated(
        since = "4.0.0",
        note = "Prefer `.add((key, value))`. Will be removed in v5."
    )]
    pub fn header<K, V>(self, key: K, value: V) -> Self
    where
        HeaderName: TryFrom<K>,
        <HeaderName as TryFrom<K>>::Error: Into<HttpError>,
        HeaderValue: TryFrom<V>,
        <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
    {
        self.add((
            HeaderName::try_from(key)
                .map_err(Into::into)
                .expect("Invalid header name"),
            HeaderValue::try_from(value)
                .map_err(Into::into)
                .expect("Invalid header value"),
        ))
    }

    /// Adds a default *Content-Type* header if response does not contain one.
    ///
    /// Default is `application/octet-stream`.
    pub fn add_content_type(self) -> Self {
        #[allow(clippy::declare_interior_mutable_const)]
        const HV_MIME: HeaderValue = HeaderValue::from_static("application/octet-stream");
        self.add((CONTENT_TYPE, HV_MIME))
    }
}

impl<S, B> Transform<S, ServiceRequest> for DefaultHeaders
where

View on GitHub (pinned to 937960ca67)

Solutions

  1. Switch to the current `.add((name, value))` API and validate the name yourself, returning a `Result` instead of panicking.
  2. Sanitize/validate header names against the token grammar before calling.
  3. Use a known-valid static name constant from `actix_web::http::header`.

Example fix

// before
mw.header(":", "v");

// after
// prefer the non-deprecated, result-friendly API:
fn try_add(mw: DefaultHeaders, k: &str, v: &str) -> Result<DefaultHeaders, actix_web::Error> {
    let name = HeaderName::try_from(k)?;
    let val = HeaderValue::try_from(v)?;
    Ok(mw.add((name, val)))
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate header names with TryFrom and handle the error instead of panicking.
use actix_web::http::header::HeaderName;
fn valid_name(k: &str) -> bool {
    HeaderName::try_from(k).is_ok()
}
// assert!(!valid_name(":"));
// assert!(valid_name("x-test"));

Type guard

fn is_valid_header_name(k: &str) -> bool {
    HeaderName::try_from(k).is_ok()
}

Prevention

When it happens

Trigger: Calling `.header(":", "v")`, `.header("Bad Name", "v")`, or any key failing RFC 7230 token rules via the deprecated method.

Common situations: Using the old `header()` API with dynamically generated or user-supplied header names.

Related errors


AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06). Data as JSON: /data/errors/b8b741e0121e3d83.json. Report an issue: GitHub.