bevyengine/bevy · error

Invalid header name

Error message

Invalid header name

What it means

`Headers` is the header map used by bevy_remote's JSON-RPC-over-HTTP transport for the Bevy Remote Protocol (served by `RemoteHttpPlugin`, by default on port 15702). `Headers::insert` is a builder-style method that converts its arguments into `hyper`'s `HeaderName`/`HeaderValue` and panics if a conversion fails, because HTTP header names must be valid tokens. This panic is the name-conversion failure branch.

Source

Thrown at crates/bevy_remote/src/http.rs:87

    headers: HashMap<HeaderName, HeaderValue>,
}

impl Headers {
    /// Create a new instance of `Headers`.
    pub fn new() -> Self {
        Self {
            headers: HashMap::default(),
        }
    }

    /// Insert a key value pair to the `Headers` instance.
    pub fn insert(
        mut self,
        name: impl TryInto<HeaderName>,
        value: impl TryInto<HeaderValue>,
    ) -> Self {
        let Ok(header_name) = name.try_into() else {
            panic!("Invalid header name")
        };
        let Ok(header_value) = value.try_into() else {
            panic!("Invalid header value")
        };
        self.headers.insert(header_name, header_value);
        self
    }
}

impl Default for Headers {
    fn default() -> Self {
        Self::new()
    }
}

/// Add this plugin to your [`App`] to allow remote connections over HTTP to inspect and modify entities.
/// It requires the [`RemotePlugin`](super::RemotePlugin).
///

View on GitHub (pinned to 396ca72708)

Solutions

  1. Fix the name to a valid HTTP token: ASCII letters, digits and hyphens only (e.g. "Session-Id")
  2. If the name is dynamic, validate it first with `hyper::header::HeaderName::from_bytes(name.as_bytes())` and skip or log invalid names
  3. Never pass unvalidated user input as a header name; use fixed names and put user data in the value

Example fix

// before
let headers = Headers::new().insert("Session ID", session_id.as_str());

// after
let headers = Headers::new().insert("Session-Id", session_id.as_str());
Defensive patterns

Strategy: validation

Validate before calling

// hyper is already in bevy_remote's dependency tree
fn valid_header_name(name: &str) -> bool {
    hyper::header::HeaderName::from_bytes(name.as_bytes()).is_ok()
}

if valid_header_name(&name) {
    headers = headers.insert(name, value);
} else {
    warn!("skipping invalid header name: {name:?}");
}

Prevention

When it happens

Trigger: Calling `headers.insert(name, value)` with a name that is not a valid HTTP token: an empty string, a name containing spaces (e.g. "Session ID"), control bytes, non-ASCII characters, or separator characters such as `()<>@,;:"/[]?={}`.

Common situations: Writing custom BRP middleware or response headers (CORS, session/auth headers) where the header name is assembled from user input, contains a space, or was copied from prose with stray whitespace.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/b78ea4d911d322be. Report an issue: GitHub.