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
- Validate the method before the request: non-empty and every byte an RFC 7230 token character (A-Z a-z 0-9 !#$%&'*+-.^_`|~).
- Uppercase and hard-code known custom verbs from an enum instead of passing arbitrary strings.
- 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
- Never pass unvalidated strings as HTTP methods from modules.
- Map allowed verbs from an enum and reject unknown ones at the boundary.
- Test module HTTP helpers with odd verbs before publishing.
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
- Route paths must start with `/`: ${path}
- Route paths may contain only ${ACCEPTABLE_ROUTE_PATH_CHARS_H
- cannot replace {} without enclosing directory
- Invalid header name from host
- Index '${indexLabel}' on table '${tableLabel}' must define a
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/cb4e49f365a25d0e.
Report an issue: GitHub.