{"record":{"id":"2f1c783f4b687bfe","repo":"denoland/deno","slug":"err-http2-unsupported-protocol","errorCode":"ERR_HTTP2_UNSUPPORTED_PROTOCOL","errorMessage":"protocol \"${protocol}\" is unsupported.","messagePattern":"protocol \"(.+?)\" is unsupported\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/http2.ts","lineNumber":5400,"sourceCode":"  }\n\n  let socket;\n  if (typeof options.createConnection === \"function\") {\n    socket = options.createConnection(authority, options);\n  } else {\n    switch (protocol) {\n      case \"http:\":\n        socket = net.connect({ port, host, ...options });\n        break;\n      case \"https:\":\n        socket = tls.connect(\n          port,\n          host,\n          initializeTLSOptions(options, net.isIP(host) ? undefined : host),\n        );\n        break;\n      default:\n        throw new ERR_HTTP2_UNSUPPORTED_PROTOCOL(protocol);\n    }\n  }\n\n  const session = new ClientHttp2Session(options, socket);\n\n  session[kAuthority] = `${options.servername || host}:${port}`;\n  session[kProtocol] = protocol;\n\n  if (typeof listener === \"function\") {\n    session.once(\"connect\", listener);\n  }\n\n  return session;\n}\n\n// Support util.promisify\nconst promisifyConnect = function (authority, options) {\n  return new Promise((resolve, reject) => {","sourceCodeStart":5382,"sourceCodeEnd":5418,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/http2.ts#L5382-L5418","documentation":"http2.connect(authority) maps the authority's URL scheme onto a transport: 'https:' creates a TLS socket via tls.connect, 'http:' a plaintext TCP socket via net.connect. The switch's default branch throws ERR_HTTP2_UNSUPPORTED_PROTOCOL for every other scheme. The scheme comes from the authority URL first, then options.protocol, then defaults to 'https:' — so the error requires an explicitly non-http(s) scheme.","triggerScenarios":"http2.connect('h2://example.com:443') (h2 is not an accepted scheme here); a URL object whose protocol is 'grpc:', 'unix:', or 'tcp:'; passing options.protocol = 'h2:' with a scheme-less authority.","commonSituations":"gRPC-style targets copied from grpc client configs ('h2://host', 'dns:///host'); Unix-domain-socket URLs; hand-built authority strings with invented schemes; uppercase schemes are fine (URL normalizes to lowercase).","solutions":["Use https://example.com for TLS HTTP/2 or http://example.com for plaintext (h2c) — h2 over TLS is implied by https:.","Convert gRPC targets: 'h2://host:port' becomes 'https://host:port'.","Normalize the authority URL (or set options.protocol) to http:/https: before calling connect; fail fast in config validation for anything else."],"exampleFix":"// before\nconst session = http2.connect('h2://example.com:443'); // ERR_HTTP2_UNSUPPORTED_PROTOCOL\n\n// after\nconst session = http2.connect('https://example.com:443');","handlingStrategy":"validation","validationCode":"function normalizeHttp2Target(authority) {\n  const u = typeof authority === 'string' ? new URL(authority) : authority;\n  if (u.protocol !== 'https:' && u.protocol !== 'http:') {\n    throw new RangeError(`http2.connect supports http:/https:, got ${u.protocol}`);\n  }\n  return u;\n}\nconst session = http2.connect(normalizeHttp2Target(target));","typeGuard":"function isSupportedHttp2Protocol(u) {\n  return u instanceof URL && (u.protocol === 'https:' || u.protocol === 'http:');\n}","tryCatchPattern":"try {\n  const session = http2.connect(authority);\n} catch (e) {\n  if (e.code === 'ERR_HTTP2_UNSUPPORTED_PROTOCOL') {\n    // normalize scheme (e.g. h2:// -> https://) and retry once\n  } else throw e;\n}","preventionTips":["Normalize every upstream target URL to http:/https: at config-load time.","Never invent schemes like h2:// or h2c:// for http2.connect — the scheme selects the transport; h2 is implied.","Reject unknown schemes during config validation instead of at connection time."],"tags":["http2","url","protocol","client","node-compat"],"backgroundTag":"unsupported-url-protocol","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}