clockworklabs/SpacetimeDB · error

Invalid HTTP method

Error message

Invalid HTTP method

What it means

SpacetimeDB modules can issue HTTP requests; non-standard methods arrive as `st_http::Method::Extension(bytes)` and are converted with `http::Method::from_bytes(...).expect("Invalid HTTP method")`. `from_bytes` fails when the bytes are not a valid RFC 7230 token: an empty string, embedded spaces/control characters, or characters outside the token set such as `/`, `?`, `,`, or non-ASCII.

Source

Thrown at crates/core/src/host/instance_env.rs:1220

        method,
        headers,
        timeout,
        uri,
        version,
    } = request;

    let (mut request, ()) = http::Request::new(()).into_parts();
    request.method = match method {
        st_http::Method::Get => http::Method::GET,
        st_http::Method::Head => http::Method::HEAD,
        st_http::Method::Post => http::Method::POST,
        st_http::Method::Put => http::Method::PUT,
        st_http::Method::Delete => http::Method::DELETE,
        st_http::Method::Connect => http::Method::CONNECT,
        st_http::Method::Options => http::Method::OPTIONS,
        st_http::Method::Trace => http::Method::TRACE,
        st_http::Method::Patch => http::Method::PATCH,
        st_http::Method::Extension(method) => http::Method::from_bytes(method.as_bytes()).expect("Invalid HTTP method"),
    };
    // The error type here, `http::uri::InvalidUri`, doesn't contain the URI itself,
    // so it's safe to return and to log.
    // See https://docs.rs/http/1.3.1/src/http/uri/mod.rs.html#120-141 .
    request.uri = uri.try_into()?;
    request.version = match version {
        st_http::Version::Http09 => http::Version::HTTP_09,
        st_http::Version::Http10 => http::Version::HTTP_10,
        st_http::Version::Http11 => http::Version::HTTP_11,
        st_http::Version::Http2 => http::Version::HTTP_2,
        st_http::Version::Http3 => http::Version::HTTP_3,
    };
    request.headers = headers
        .into_iter()
        .map(|(k, v)| {
            Ok((
                // The error type here, `http::header::InvalidHeaderName`, doesn't contain the header name itself,
                // so it's safe to return and to log.

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Validate the method before the request: non-empty and every byte an RFC 7230 token character (A-Z a-z 0-9 !#$%&'*+-.^_`|~).
  2. Uppercase and hard-code known custom verbs from an enum instead of passing arbitrary strings.
  3. If the method originates from untrusted input, reject invalid tokens early with a reducer error instead of letting the module panic.

Example fix

// before: arbitrary string panics on invalid bytes
let method = st_http::Method::Extension(method_str.into());

// after: validate the token first
fn is_http_token(s: &str) -> bool {
    !s.is_empty() && s.bytes().all(|b|
        b.is_ascii_alphanumeric() || matches!(b, b'-' | b'.' | b'_' | b'~' | b'!' | b'#' | b'$' | b'%' | b'&' | b'\'' | b'*' | b'+' | b'^' | b'`' | b'|'))
}
assert!(is_http_token(&method_str), "invalid HTTP method token");
Defensive patterns

Strategy: validation

Validate before calling

fn is_http_token(s: &str) -> bool {
    !s.is_empty() && s.bytes().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'-' | b'.' | b'_' | b'~' | b'!' | b'#' | b'$' | b'%' | b'&' | b'\'' | b'*' | b'+' | b'^' | b'`' | b'|'))
}
assert!(is_http_token(&custom_method), "invalid HTTP method");

Prevention

When it happens

Trigger: Calling the module HTTP client API with an extension method like "FOO BAR", an empty string, a method with trailing CR/LF or whitespace, or non-ASCII bytes (e.g. "MÉTHODE") — anything outside A-Z a-z 0-9 and !#$%&'*+-.^_`|~.

Common situations: Building the method dynamically from user input or config without validation; WebDAV-style custom verbs ("VERSION-CONTROL" is valid) concatenated with stray whitespace/newlines; lowercase custom verbs are accepted but injected separators are not.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/cb4e49f365a25d0e. Report an issue: GitHub.