denoland/deno · error · NodeError
ERR_HTTP2_CONNECT_AUTHORITY
ERR_HTTP2_CONNECT_AUTHORITY
Error message
:authority header is required for CONNECT requests
What it means
For HTTP/2 CONNECT requests built from a headers ARRAY, the ':authority' pseudo-header is mandatory (RFC 7540 section 8.3: CONNECT must carry :authority and must omit :scheme/:path). If method is CONNECT and no authority was resolved from the array, prepareRequestHeadersArray throws ERR_HTTP2_CONNECT_AUTHORITY (util.ts:690).
Source
Thrown at ext/node/polyfills/internal/http2/util.ts:690
if (!connect || protocol !== undefined) {
if (authority === undefined && headers[HTTP2_HEADER_HOST] === undefined) {
authority = session[kAuthority];
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(View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Add ':authority' with host:port to the headers array, e.g. [':method','CONNECT',':authority','example.com:443'].
- If the authority arrives as a Host header, map it: [':authority', hostHeader].
- Make sure you do not over-correct by also adding ':scheme' or ':path' — those throw ERR_HTTP2_CONNECT_SCHEME/PATH.
Example fix
// before client.request([':method', 'CONNECT', ':path', '/']); // throws // after client.request([':method', 'CONNECT', ':authority', 'example.com:443']);
Defensive patterns
Strategy: validation
Validate before calling
const isConnect = (h) => h[':method'] === 'CONNECT' || h.includes?.('CONNECT');
if (isConnect(headers) && !hasAuthority(headers)) {
headers = [...headers, ':authority', targetHost]; // or headers[':authority'] = targetHost
} Try / catch
try { session.request(h); } catch (e) { if (e.code === 'ERR_HTTP2_CONNECT_AUTHORITY') { /* inject ':authority' from your target and retry */ } throw e; } Prevention
- For CONNECT always set :authority to host:port
- Do not rely on a 'host' header to carry CONNECT authority
When it happens
Trigger: Calling http2session.request([':method','CONNECT', ...]) or client.request(...) with method CONNECT and headers lacking ':authority' (and no host/authority fallback), e.g. [':method','CONNECT',':path','/tunnel'].
Common situations: Writing HTTP/2 tunneling/CONNECT-proxy code by copying a normal GET request template; forwarding a browser CONNECT request where the authority lived in a Host header that was dropped; version upgrades from HTTP/1 proxy code where Host: was implicit.
Related errors
- ERR_HTTP2_CONNECT_SCHEME
- ERR_HTTP2_CONNECT_PATH
- ERR_HTTP2_INVALID_CONNECTION_HEADERS
- ERR_INVALID_ARG_VALUE
- ERR_HTTP2_INVALID_PSEUDOHEADER
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/20a99c7a656f997b.
Report an issue: GitHub.