denoland/deno · error · NodeError

ERR_HTTP2_CONNECT_PATH

ERR_HTTP2_CONNECT_PATH

Error message

The :path header is forbidden for CONNECT requests

What it means

HTTP/2 CONNECT requests must not carry the ':path' pseudo-header (RFC 7540 section 8.3). When preparing a headers array for a CONNECT request, a defined :path throws ERR_HTTP2_CONNECT_PATH (util.ts:696) — CONNECT tunnels identify the target via :authority only.

Source

Thrown at ext/node/polyfills/internal/http2/util.ts:696

        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],
  );

  return {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Remove ':path' entirely from the headers array for CONNECT requests (do not set it to '' — undefined is the only safe state).
  2. Guard your header builder: if (method === 'CONNECT') push only :method and :authority.
  3. Log the final headers array right before request() during development to catch injected defaults.

Example fix

// before
client.request([':method', 'CONNECT', ':authority', 'h:443', ':path', '/']);

// after
client.request([':method', 'CONNECT', ':authority', 'h:443']);
Defensive patterns

Strategy: validation

Validate before calling

if (method === 'CONNECT') { headers = headers.filter((k, i) => i % 2 === 1 || k !== ':path'); }

Prevention

When it happens

Trigger: http2session.request() with ':method','CONNECT' and ':path' present in the headers array, e.g. [':method','CONNECT',':authority','h:443',':path','/tunnel']. Empty-string :path also counts as defined and still throws.

Common situations: Default request templates that always set :path:'/'; CONNECT proxies forwarding an origin-form target as a path; shared header builders that inject defaults for every request type.

Understand the failure class

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/48b16275b5c2e173. Report an issue: GitHub.