{"record":{"id":"69f4976efe2de082","repo":"denoland/deno","slug":"err-http2-too-many-custom-settings-69f497","errorCode":"ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS","errorMessage":"Number of custom settings exceeds MAX_ADDITIONAL_SETTINGS","messagePattern":"Number of custom settings exceeds MAX_ADDITIONAL_SETTINGS","errorType":"validation","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/http2/util.ts","lineNumber":471,"sourceCode":"            default:\n              set = false;\n              break;\n          }\n        }\n        if (!set) { // not supported\n          let i = 0;\n          while (i < numCustomSettings) {\n            if (\n              settingsBuffer[IDX_SETTINGS_FLAGS + 1 + 2 * i + 1] === nsetting\n            ) {\n              settingsBuffer[IDX_SETTINGS_FLAGS + 1 + 2 * i + 2] = val;\n              break;\n            }\n            i++;\n          }\n          if (i === numCustomSettings) {\n            if (numCustomSettings === MAX_ADDITIONAL_SETTINGS) {\n              throw new ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS();\n            }\n\n            settingsBuffer[IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 1] =\n              nsetting;\n            settingsBuffer[IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 2] =\n              val;\n            numCustomSettings++;\n          }\n        }\n      }\n    }\n  }\n  settingsBuffer[IDX_SETTINGS_FLAGS + 1] = numCustomSettings;\n\n  if (typeof settings.headerTableSize === \"number\") {\n    flags |= 1 << IDX_SETTINGS_HEADER_TABLE_SIZE;\n    settingsBuffer[IDX_SETTINGS_HEADER_TABLE_SIZE] = settings.headerTableSize;\n  }","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/http2/util.ts#L453-L489","documentation":"The SETTINGS packer in http2/util.ts allows at most MAX_ADDITIONAL_SETTINGS (10, util.ts:217) custom (non-standard) setting identifiers. When an 11th distinct id would be appended to the settings buffer, ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS is thrown before the frame goes out.","triggerScenarios":"Passing settings.customSettings with 11+ distinct numeric keys to http2.createServer() or http2.connect(); merging custom settings from multiple modules (tracing + A/B tests + client hints) into one object that exceeds the cap.","commonSituations":"Feature-flag-heavy setups tunneling many experimental nghttp2 settings; config systems that deep-merge everyone's customSettings into one blob; code copied between client and server that doubles the id count.","solutions":["Trim customSettings to at most 10 distinct ids, keeping the most important first","Prefer standard named settings (headerTableSize, initialWindowSize, maxFrameSize, ...) which do not count toward the custom limit","Centralize settings assembly and enforce the cap with an assertion"],"exampleFix":"// before\nconst custom = { ...tracing, ...abTests, ...clientHints }; // 13 distinct ids -> throw\n\n// after\nconst custom = Object.fromEntries(\n  Object.entries({ ...tracing, ...abTests, ...clientHints }).slice(0, 10),\n);","handlingStrategy":"validation","validationCode":"const MAX_CUSTOM = 10;\nfunction clampCustomSettings(cs = {}) {\n  return Object.fromEntries(Object.entries(cs).slice(0, MAX_CUSTOM));\n}\nsettings.customSettings = clampCustomSettings(mergedCustom);","typeGuard":null,"tryCatchPattern":"try {\n  session = http2.connect(url, { settings });\n} catch (err) {\n  if (err.code === \"ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS\") {\n    settings.customSettings = Object.fromEntries(\n      Object.entries(settings.customSettings ?? {}).slice(0, 10),\n    );\n    session = http2.connect(url, { settings });\n  } else throw err;\n}","preventionTips":["Keep custom settings under 10 ids; audit merged config at startup","Use standard named settings where possible — they do not count toward the cap"],"tags":["http2","settings","limits"],"backgroundTag":"http2-settings-validation","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}