denoland/deno · error · NodeError
ERR_HTTP2_CONNECT_SCHEME
ERR_HTTP2_CONNECT_SCHEME
Error message
The :scheme header is forbidden for CONNECT requests
What it means
HTTP/2 CONNECT requests must not carry the ':scheme' pseudo-header (RFC 7540 section 8.3). When preparing a headers array for a CONNECT request, presence of :scheme throws ERR_HTTP2_CONNECT_SCHEME (util.ts:693). The check is strict: even a matching scheme ('http'/'https') is rejected.
Source
Thrown at ext/node/polyfills/internal/http2/util.ts:693
ArrayPrototypePush(
additionalPsuedoHeaders,
HTTP2_HEADER_AUTHORITY,
authority,
);
}
if (scheme === undefined) {
scheme = StringPrototypeSlice(session[kProtocol], 0, -1);
ArrayPrototypePush(additionalPsuedoHeaders, HTTP2_HEADER_SCHEME, scheme);
}
if (path === undefined) {
ArrayPrototypePush(additionalPsuedoHeaders, HTTP2_HEADER_PATH, "/");
}
} else {
if (authority === undefined) {
throw new ERR_HTTP2_CONNECT_AUTHORITY();
}
if (scheme !== undefined) {
throw new ERR_HTTP2_CONNECT_SCHEME();
}
if (path !== undefined) {
throw new ERR_HTTP2_CONNECT_PATH();
}
}
const rawHeaders = additionalPsuedoHeaders.length
? ArrayPrototypeConcat(additionalPsuedoHeaders, headers)
: headers;
if (headers[kSensitiveHeaders] !== undefined) {
rawHeaders[kSensitiveHeaders] = headers[kSensitiveHeaders];
}
const headersList = buildNgHeaderString(
rawHeaders,
assertValidPseudoHeader,
session[kStrictSingleValueFields],View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Delete ':scheme' from the headers array when the method is CONNECT.
- Split your request builder: one path for normal requests (defaults :scheme/:path) and one minimal path for CONNECT (only :method + :authority).
- In generic forwarders, filter the pseudo-header set by method before calling request().
Example fix
// before const h = [...commonDefaults, ':scheme', 'https', ':method', 'CONNECT', ':authority', 'h:443']; // after const h = [':method', 'CONNECT', ':authority', 'h:443'];
Defensive patterns
Strategy: validation
Validate before calling
if (method === 'CONNECT') { headers = headers.filter((k, i) => i % 2 === 1 || k !== ':scheme'); } Prevention
- Split request builders: normal requests vs CONNECT
- Assert CONNECT header arrays contain only :method and :authority
When it happens
Trigger: http2session.request() with ':method','CONNECT' plus ':scheme','https' in the headers array — usually a CONNECT request cloned from a normal request template that fills in :scheme automatically.
Common situations: Shared helper functions that always inject :scheme/:path defaults for normal requests being reused for CONNECT; proxy code ported from HTTP/1 where scheme was harmless; template objects spread into per-request headers.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ERR_HTTP2_CONNECT_PATH
- ERR_HTTP2_CONNECT_AUTHORITY
- ERR_HTTP2_INVALID_PSEUDOHEADER
- ERR_HTTP2_INVALID_CONNECTION_HEADERS
- ERR_INVALID_URL
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/6a8fddb6c502dfbe.
Report an issue: GitHub.