seanmonstar/warp · error

invalid host/authority

Error message

invalid host/authority

What it means

`warp::host::exact(expected)` parses its argument into an `Authority` and panics with "invalid host/authority" if parsing fails (src/filters/host.rs:24). Since routing on virtual hosts must compare against well-formed HTTP authorities, warp treats a malformed expected host as a programmer error at filter-construction time rather than a runtime rejection. The panic happens when you build the filter, not when a request arrives.

Solutions

  1. Pass only the host (optionally with port): `warp::host::exact("foo.com")` or `exact("foo.com:8080")`
  2. Strip scheme/path/whitespace from config values before building the filter
  3. Trim and check the string is non-empty and parses via `http::uri::Authority::from_str` before calling `exact`
  4. Normalize hostnames to lowercase, since Authority comparison is case-sensitive per byte

Example fix

// before
let filter = warp::host::exact(std::env::var("HOST").unwrap());
// after
let host = std::env::var("HOST").unwrap().trim().to_string();
assert!(!host.is_empty(), "HOST must not be empty");
http::uri::Authority::from_str(&host).expect("HOST env var is not a valid authority");
let filter = warp::host::exact(&host);
Defensive patterns

Strategy: validation

Validate before calling

fn validate_authority(s: &str) -> Result<(), String> {
    use std::str::FromStr;
    if s.trim() != s || s.is_empty() {
        return Err("host must be non-empty with no whitespace".into());
    }
    http::uri::Authority::from_str(s).map(|_| ()).map_err(|e| format!("invalid authority '{}': {}", s, e))
}

Type guard

fn is_valid_authority(s: &str) -> bool {
    use std::str::FromStr;
    !s.trim().is_empty() && http::uri::Authority::from_str(s.trim()).is_ok()
}

Prevention

When it happens

Trigger: Calling `warp::host::exact("foo .com")`, `exact("")`, `exact("host with space")`, hosts with invalid characters (underscores in some positions, control chars), or values read from config/env that include a scheme or path like "https://foo.com".

Common situations: Feeding a full URL from config into `host::exact` instead of just the hostname; empty env vars (HOST="") at deploy time; trailing slashes or ports out of range (port > 65535); uppercase/whitespace from copy-paste.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of seanmonstar/warp@ff34d7213e (2026-09-09). Data as JSON: /api/errors/97a1c1314b6687ee. Report an issue: GitHub.

Appendix: source

Thrown at src/filters/host.rs:24

pub use http::uri::Authority;
use std::str::FromStr;

/// Creates a `Filter` that requires a specific authority (target server's
/// host and port) in the request.
///
/// Authority is specified either in the `Host` header or in the target URI.
///
/// # Example
///
/// ```
/// use warp::Filter;
///
/// let multihost =
///     warp::host::exact("foo.com").map(|| "you've reached foo.com")
///     .or(warp::host::exact("bar.com").map(|| "you've reached bar.com"));
/// ```
pub fn exact(expected: &str) -> impl Filter<Extract = (), Error = Rejection> + Clone {
    let expected = Authority::from_str(expected).expect("invalid host/authority");
    optional()
        .and_then(move |option: Option<Authority>| match option {
            Some(authority) if authority == expected => future::ok(()),
            _ => future::err(reject::not_found()),
        })
        .untuple_one()
}

/// Creates a `Filter` that looks for an authority (target server's host
/// and port) in the request.
///
/// Authority is specified either in the `Host` header or in the target URI.
///
/// If found, extracts the `Authority`, otherwise continues the request,
/// extracting `None`.
///
/// Rejects with `400 Bad Request` if the `Host` header is malformed or if there
/// is a mismatch between the `Host` header and the target URI.

View on GitHub (pinned to ff34d7213e)