actix/actix-web · error

Invalid header name

Error message

Invalid header name

What it means

This is a runtime panic from the deprecated `DefaultHeaders::header()` method. When the provided key cannot be converted into a valid `HeaderName` via `HeaderName::try_from(key)`, the `.expect("Invalid header name")` at line 91 panics. Header names must be valid ASCII tokens without spaces, colons, or other invalid characters.

Solutions

  1. Migrate to the `.add((key, value))` API which panics with a more descriptive message but is the current API
  2. Validate header names before passing them: use `HeaderName::try_from(key)` and handle the error gracefully
  3. Ensure header names are valid RFC 7230 tokens: ASCII letters, digits, and the characters `!#$%&'*+-.^_`|~`
  4. Avoid using the deprecated `.header()` method; use `.add()` instead

Example fix

// before (deprecated, panics on invalid name)
let mw = DefaultHeaders::new().header(":", "hello");

// after (validated, does not panic)
let mw = DefaultHeaders::new();
if let Ok(name) = HeaderName::try_from("x-valid-name") {
    let mw = mw.add((name, "hello"));
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate header names before passing to the middleware.
use actix_web::http::header::HeaderName;

fn safe_add(mw: DefaultHeaders, name: &str, value: &str) -> DefaultHeaders {
    match (HeaderName::try_from(name), value.try_into()) {
        (Ok(n), Ok(v)) => mw.add((n, v)),
        _ => mw, // skip invalid header
    }
}

Type guard

use actix_web::http::header::HeaderName;

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

Try / catch

// Do not use the deprecated .header() method. Use .add() which validates at construction.
// For dynamic header names, validate first:
let mw = DefaultHeaders::new();
for (name, value) in user_headers {
    if is_valid_header_name(name) {
        mw.add((name, value));
    }
}

Prevention

When it happens

Trigger: Calling the deprecated `.header(key, value)` method with an invalid header name such as `":"`, `"hello world"`, `"Content-Type:"` (trailing colon), or a non-ASCII string. The `http` crate's `HeaderName` type has strict validation rules.

Common situations: Using the old `.header()` API instead of the preferred `.add()` method, or dynamically constructing header names from user input without validation.

Related errors


AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09). Data as JSON: /api/errors/b8b741e0121e3d83. Report an issue: GitHub.

Appendix: 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 4d435abc28)