denoland/deno · error · NodeTypeError
ERR_INVALID_HTTP_TOKEN
ERR_INVALID_HTTP_TOKEN
Error message
Method must be a valid HTTP token ["${method}"] What it means
After confirming options.method is a non-empty string, ClientRequest runs checkIsHttpToken on it. Methods must be a valid HTTP token (RFC 7230 tchar: alphanumerics and !#$%&'*+-.^_`|~). A string containing spaces, slashes, newlines, or other delimiters throws ERR_INVALID_HTTP_TOKEN. Valid methods are then uppercased and stored.
Source
Thrown at ext/node/polyfills/_http_client.js:614
if (options.timeout !== undefined) {
this.timeout = getTimerDuration(options.timeout, "timeout");
}
const signal = options.signal;
if (signal) {
addAbortSignal(signal, this);
delete optsWithoutSignal.signal;
}
let method = options.method;
if (method != null) {
if (typeof method !== "string") {
throw new ERR_INVALID_ARG_TYPE("options.method", "string", method);
}
}
if (method) {
if (!checkIsHttpToken(method)) {
throw new ERR_INVALID_HTTP_TOKEN("Method", method);
}
method = this.method = StringPrototypeToUpperCase(method);
} else {
method = this.method = "GET";
}
const maxHeaderSize = options.maxHeaderSize;
if (maxHeaderSize !== undefined) {
validateInteger(maxHeaderSize, "maxHeaderSize", 0);
}
this.maxHeaderSize = maxHeaderSize;
const insecureHTTPParser = options.insecureHTTPParser;
if (insecureHTTPParser !== undefined) {
validateBoolean(insecureHTTPParser, "options.insecureHTTPParser");
}
this.insecureHTTPParser = insecureHTTPParser;
View on GitHub (pinned to 89f33cbef2)
Solutions
- Pass only the verb: extract tokens[0] when parsing a request line
- Trim and validate against the token charset before the call: /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
- Reject or map unknown custom methods to a safe verb instead of forwarding raw strings
Example fix
// before
const method = rawLine; // 'GET /index HTTP/1.1'
const req = http.request({ host, method });
// after
const method = rawLine.split(' ')[0].trim();
const req = http.request({ host, method }); Defensive patterns
Strategy: validation
Validate before calling
const HTTP_TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
if (method && !HTTP_TOKEN.test(method)) {
throw new Error(`invalid HTTP method: ${JSON.stringify(method)}`);
}
http.request({ host, method }); Type guard
const isHttpToken = (s) => typeof s === 'string' && s.length > 0 && /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(s);
Try / catch
try { http.request({ method }); } catch (e) { if (e.code === 'ERR_INVALID_HTTP_TOKEN') { /* sanitize: method = method.trim().split(' ')[0] */ } else throw e; } Prevention
- When parsing raw request lines, take only the first token as method
- Trim whitespace from config-sourced methods
- Whitelist allowed verbs instead of passing raw strings through
When it happens
Trigger: Passing a whole request line as the method: { method: 'GET /x HTTP/1.1' }; method: 'get\n' from unsanitized input; custom verbs with invalid characters like 'FETCH+' or 'my method'.
Common situations: Splitting raw HTTP text manually and grabbing the wrong token; log or config lines with trailing whitespace/newlines used as method; WebDAV-style custom verbs constructed from user input without sanitization.
Related errors
- ERR_INVALID_HTTP_TOKEN
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_URL
- ERR_UNESCAPED_CHARACTERS
- ERR_HTTP_CONTENT_LENGTH_MISMATCH
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/764738baee9eda0d.
Report an issue: GitHub.