denoland/deno · error · NodeRangeError
ERR_HTTP2_INVALID_SETTING_VALUE
ERR_HTTP2_INVALID_SETTING_VALUE
Error message
Invalid value for setting "Range Error": ${nsetting} What it means
While packing session settings, http2/util.ts validates each customSettings entry: the setting identifier (the object key, coerced with Number()) must be a numeric value in 1..0xffff. A key that is not numeric, NaN, <= 0, or > 0xffff throws ERR_HTTP2_INVALID_SETTING_VALUE (RangeError variant) with the offending identifier in the message. customSettings keys are numeric HTTP/2 setting IDs, never names.
Source
Thrown at ext/node/polyfills/internal/http2/util.ts:402
function updateSettingsBuffer(settings) {
ensureHttpStateBuffers();
let flags = 0;
let numCustomSettings = 0;
if (typeof settings.customSettings === "object") {
const customSettings = settings.customSettings;
for (const setting in customSettings) {
const val = customSettings[setting];
if (typeof val === "number") {
let set = false;
const nsetting = Number(setting);
if (
NumberIsNaN(nsetting) ||
typeof nsetting !== "number" ||
0 >= nsetting ||
nsetting > 0xffff
) {
throw new ERR_HTTP2_INVALID_SETTING_VALUE.RangeError(
"Range Error",
nsetting,
0,
0xffff,
);
}
if (
NumberIsNaN(val) ||
typeof val !== "number" ||
0 >= val ||
val > 0xffffffff
) {
throw new ERR_HTTP2_INVALID_SETTING_VALUE.RangeError(
"Range Error",
val,
0,
0xffffffff,
);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use numeric keys in 1-65535: customSettings: { 0xff02: 1 } — write them as numbers, not names
- Use http2.constants / documented IDs for known experimental settings
- Validate keys before connect: Number(key) is an integer within 1..65535
Example fix
// before
http2.connect("https://example.com", {
settings: { customSettings: { enableFoo: 1 } }, // key -> NaN -> throw
});
// after
http2.connect("https://example.com", {
settings: { customSettings: { 65278: 1 } }, // numeric setting id
}); Defensive patterns
Strategy: validation
Validate before calling
function validCustomSettingIds(cs = {}) {
return Object.keys(cs).every((k) => {
const id = Number(k);
return Number.isInteger(id) && id >= 1 && id <= 0xffff;
});
}
if (validCustomSettingIds(settings.customSettings)) {
session = http2.connect(url, { settings });
} Type guard
function isCustomSettingsMap(
cs: unknown,
): cs is Record<number, number> {
if (cs == null) return true;
return Object.entries(cs).every(([k, v]) => {
const id = Number(k);
return Number.isInteger(id) && id >= 1 && id <= 0xffff &&
Number.isFinite(v as number) && (v as number) >= 1 &&
(v as number) <= 0xffffffff;
});
} Try / catch
try {
session = http2.connect(url, { settings });
} catch (err) {
if (err.code === "ERR_HTTP2_INVALID_SETTING_VALUE") {
delete settings.customSettings; // drop bad ids and retry with standard settings
session = http2.connect(url, { settings });
} else throw err;
} Prevention
- Remember customSettings keys are numeric HTTP/2 setting IDs, never names
- Range-check ids (1-65535) and values (1-4294967295) in one helper before connect
When it happens
Trigger: http2.connect(url, { settings: { customSettings: { enableFoo: 1 } } }) — key 'enableFoo' coerces to NaN; { '0': 1 } (zero rejected); { '70000': 1 } (> 0xffff); float keys like '1.5'.
Common situations: Copied snippets using descriptive string names for experimental settings; porting nghttp2 numeric constants as strings that overflow; assuming any object key works because TypeScript types it as Record<string, number>.
Related errors
- ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH
- ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS
- ERR_HTTP2_INVALID_SETTING_VALUE
- ERR_HTTP2_PUSH_DISABLED
- ERR_INVALID_HTTP_TOKEN
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/59324efa24d430fc.
Report an issue: GitHub.