{"record":{"id":"614941790b6977c7","repo":"denoland/deno","slug":"err-http2-origin-length","errorCode":"ERR_HTTP2_ORIGIN_LENGTH","errorMessage":"HTTP/2 ORIGIN frames are limited to 16382 bytes","messagePattern":"HTTP/2 ORIGIN frames are limited to 16382 bytes","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/http2.ts","lineNumber":4664,"sourceCode":"    const count = origins.length;\n    for (let i = 0; i < count; i++) {\n      let origin = origins[i];\n      if (typeof origin === \"string\") {\n        origin = getURLOrigin(origin);\n      } else if (origin != null && typeof origin === \"object\") {\n        origin = origin.origin;\n      }\n      validateString(origin, \"origin\");\n      if (origin === \"null\") {\n        throw new ERR_HTTP2_INVALID_ORIGIN();\n      }\n\n      arr += `${origin}\\0`;\n      len += origin.length;\n    }\n\n    if (len > kMaxALTSVC) {\n      throw new ERR_HTTP2_ORIGIN_LENGTH();\n    }\n\n    this[kHandle].origin(arr, count);\n  }\n}\n\n// ClientHttp2Session instances have to wait for the socket to connect after\n// they have been created. Various operations such as request() may be used,\n// but the actual protocol communication will only occur after the socket\n// has been connected.\nclass ClientHttp2Session extends Http2Session {\n  constructor(options, socket) {\n    initCallbacks();\n    super(NGHTTP2_SESSION_CLIENT, options, socket);\n    this[kPendingRequestCalls] = null;\n  }\n\n  // Submits a new HTTP2 request to the connected peer. Returns the","sourceCodeStart":4646,"sourceCodeEnd":4682,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/http2.ts#L4646-L4682","documentation":"origin() concatenates all validated origins (each followed by a NUL byte) into one frame payload, and the sum of the origin string lengths (len, not counting the separators) must stay within kMaxALTSVC = 16382 bytes. Exceeding it throws ERR_HTTP2_ORIGIN_LENGTH, reusing the same 16-bit length budget as ALTSVC, because one frame cannot carry the list.","triggerScenarios":"Passing hundreds or thousands of origins in a single session.origin(...origins) call such that the combined origin strings exceed 16382 characters.","commonSituations":"Wildcard-multi-tenant servers enumerating every tenant hostname in one call; origin lists generated from DNS zone files; a growing origin list that slowly approaches the limit across deployments.","solutions":["Split the origins across multiple session.origin() calls — each call emits its own frame","Reduce the list to origins the client will actually coalesce over this connection","Chunk the list: for (let i = 0; i < origins.length; i += 500) session.origin(...origins.slice(i, i + 500))"],"exampleFix":"// before\nsession.origin(...allOrigins); // combined length > 16382\n\n// after\nconst CHUNK = 500;\nfor (let i = 0; i < allOrigins.length; i += CHUNK) {\n  session.origin(...allOrigins.slice(i, i + CHUNK));\n}","handlingStrategy":"validation","validationCode":"const CHUNK = 500;\nfor (let i = 0; i < origins.length; i += CHUNK) {\n  session.origin(...origins.slice(i, i + CHUNK));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["The 16382-byte budget counts the sum of origin string lengths, not the array length","Chunk large lists — each origin() call emits its own frame","Trim the list to origins actually served on this connection's certificate"],"tags":["http2","node-compat","origin-frame","size-limit"],"backgroundTag":"payload-too-large","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}