actix/actix-web · critical
Invalid header value
Error message
Invalid header value
What it means
The deprecated `DefaultHeaders::header()` helper at actix-web/src/middleware/default_headers.rs:92-95 converts the value with `HeaderValue::try_from` and `.expect("Invalid header value")`. Values containing illegal bytes (e.g. control characters, a raw newline `\n`) panic.
Source
Thrown at actix-web/src/middleware/default_headers.rs:94
#[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
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
{View on GitHub (pinned to 937960ca67)
Solutions
- Use the `.add((name, value))` API and validate the value first, handling the error.
- Strip or reject CR/LF and other control bytes from any dynamic value.
- For ASCII-only values, consider percent-encoding or base64-encoding binary data.
Example fix
// before
mw.header("X-Test", user_input); // panics if user_input has \n
// after
fn try_add(mw: DefaultHeaders, v: &str) -> Result<DefaultHeaders, actix_web::Error> {
let val = HeaderValue::try_from(v)?;
Ok(mw.add(("X-Test", val)))
} Defensive patterns
Strategy: validation
Validate before calling
// Validate header values; reject CR/LF and control bytes.
use actix_web::http::header::HeaderValue;
fn valid_value(v: &str) -> bool {
HeaderValue::try_from(v).is_ok()
}
// assert!(!valid_value("\n"));
// assert!(valid_value("ok")); Type guard
fn is_valid_header_value(v: &str) -> bool {
!v.bytes().any(|b| b == b'\r' || b == b'\n' || b.is_ascii_control())
&& HeaderValue::try_from(v).is_ok()
} Prevention
- Migrate to .add((name, value)) and handle the Result.
- Sanitize untrusted strings before placing them in headers (prevents injection).
When it happens
Trigger: Calling `.header("X-Test", "\n")` or passing user input containing CR/LF or other forbidden bytes.
Common situations: Embedding untrusted strings into a header value without sanitization (header injection risk).
Related errors
- Invalid header name
- All default headers must be added before cloning.
- cannot reuse response builder
- Unsupported HTTP version: {:?}.
- actix-http client only supports versions http/1.1 & http/2
AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06).
Data as JSON: /data/errors/57daefdab67a0ae0.json.
Report an issue: GitHub.