seanmonstar/warp · error
invalid header name
Error message
invalid header name
What it means
The reply::WithHeader/WithHeaders extension panics with 'invalid header name' when the header key passed to reply::with_header cannot be converted into an http::HeaderName via assert_name_and_value. Invalid keys (empty strings, non-token characters) are treated as programmer errors.
Solutions
- Use a valid header name literal or an http::header:: constant
- Validate the dynamic key with HeaderName::try_from before calling with_header
- Fix string-building logic that produces empty or malformed names
Example fix
// before
reply::with_header(&format!("{}-{}", prefix, suffix), "v")
// after
let name = format!("{}-{}", prefix, suffix);
assert!(HeaderName::try_from(name.as_str()).is_ok(), "invalid header name");
reply::with_header(name, "v") Defensive patterns
Strategy: validation
Validate before calling
if HeaderName::try_from(name.as_str()).is_err() { panic!("bad reply header name: {}", name); } Type guard
fn valid_reply_header_name(k: &str) -> Option<HeaderName> { HeaderName::try_from(k).ok() } Prevention
- Use http::header:: constants for static headers
- Check dynamically-built names for emptiness/invalid chars
- Unit-test reply construction with production header values
When it happens
Trigger: reply::with_header("", "value"), reply::with_header("bad header", "v"), or any dynamic key failing HeaderName conversion when attaching headers to a reply.
Common situations: Injecting headers from request-derived or config-derived strings; typos like 'Content- Type'; constructing names by concatenation producing empty/invalid results.
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/bfbf284e36107755.
Report an issue: GitHub.
Appendix: source
Thrown at src/filters/reply.rs:189
{
type Wrapped = Map<F, WithDefaultHeader_>;
fn wrap(&self, filter: F) -> Self::Wrapped {
let with = WithDefaultHeader_ { with: self.clone() };
filter.map(with)
}
}
fn assert_name_and_value<K, V>(name: K, value: V) -> (HeaderName, HeaderValue)
where
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<http::Error>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
{
let name = <HeaderName as TryFrom<K>>::try_from(name)
.map_err(Into::into)
.unwrap_or_else(|_| panic!("invalid header name"));
let value = <HeaderValue as TryFrom<V>>::try_from(value)
.map_err(Into::into)
.unwrap_or_else(|_| panic!("invalid header value"));
(name, value)
}
mod sealed {
use super::{WithDefaultHeader, WithHeader, WithHeaders};
use crate::generic::{Func, One};
use crate::reply::{Reply, Reply_};
#[derive(Clone)]
#[allow(missing_debug_implementations)]
pub struct WithHeader_ {
pub(super) with: WithHeader,
}View on GitHub (pinned to ff34d7213e)