{"record":{"id":"6dc2e678962b8c66","repo":"denoland/deno","slug":"unsupported-alpnprotocols-option-provided-h2","errorCode":null,"errorMessage":"Unsupported 'alpnProtocols' option provided. 'h2' and 'http/1.1' are automatically supported.","messagePattern":"Unsupported 'alpnProtocols' option provided\\. 'h2' and 'http/1\\.1' are automatically supported\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/http/00_serve.ts","lineNumber":1374,"sourceCode":"      automaticCompression,\n    );\n  }\n\n  const listenOpts = {\n    hostname: options.hostname ?? \"0.0.0.0\",\n    port: options.port ?? 8000,\n    reusePort: options.reusePort ?? false,\n    loadBalanced: options[kLoadBalanced] ?? false,\n    tcpBacklog: options.tcpBacklog,\n  };\n\n  if (options.certFile || options.keyFile) {\n    throw new TypeError(\n      \"Unsupported 'certFile' / 'keyFile' options provided: use 'cert' / 'key' instead.\",\n    );\n  }\n  if (options.alpnProtocols) {\n    throw new TypeError(\n      \"Unsupported 'alpnProtocols' option provided. 'h2' and 'http/1.1' are automatically supported.\",\n    );\n  }\n\n  let listener;\n  if (wantsHttps) {\n    if (!options.cert || !options.key) {\n      throw new TypeError(\n        \"Both 'cert' and 'key' must be provided to enable HTTPS\",\n      );\n    }\n    listenOpts.cert = options.cert;\n    listenOpts.key = options.key;\n    listenOpts.alpnProtocols = [\"h2\", \"http/1.1\"];\n    listener = listenTls(listenOpts);\n    listenOpts.port = listener.addr.port;\n  } else {\n    listener = listen(listenOpts);","sourceCodeStart":1356,"sourceCodeEnd":1392,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/http/00_serve.ts#L1356-L1392","documentation":"Some environments (notably Node's TLS APIs) let callers configure ALPN protocol negotiation. Deno's Hyper-based HTTP server always negotiates h2 and http/1.1 automatically over TLS, so the alpnProtocols option is not supported; passing it throws this TypeError at startup to make the unsupported surface explicit.","triggerScenarios":"Including alpnProtocols: ['h2', 'http/1.1'] (or any value) in the serve options when enabling HTTPS with cert/key.","commonSituations":"Porting Node.js https.createServer TLS options verbatim to Deno.serve; config templates that carry Node-style ALPN lists.","solutions":["Delete the alpnProtocols option; h2 and http/1.1 are already supported automatically","If you depended on restricting protocols, note that Deno does not expose ALPN selection and serves both","Keep cert/key for TLS and drop all Node-only TLS options when migrating"],"exampleFix":"// before\nDeno.serve({\n  port: 443,\n  cert,\n  key,\n  alpnProtocols: [\"h2\", \"http/1.1\"], // unsupported option\n  handler,\n});\n\n// after\nDeno.serve({ port: 443, cert, key, handler }); // ALPN negotiated automatically","handlingStrategy":"validation","validationCode":"// Strip unsupported TLS options before serving\nfunction stripUnsupportedTls(o) {\n  const { alpnProtocols: _ignored, ...rest } = o;\n  return rest;\n}\nDeno.serve(stripUnsupportedTls({ ...options, handler }));","typeGuard":"function hasUnsupportedTlsOptions(o) {\n  return \"alpnProtocols\" in o;\n}","tryCatchPattern":null,"preventionTips":["Do not copy Node https.createServer TLS options into Deno.serve","Rely on automatic h2/http1.1 negotiation over TLS","Audit TLS config keys against Deno's ServeTlsOptions type during migration"],"tags":["http","serve","tls","alpn","node-compat"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}