denoland/deno · error · NodeRangeError
ERR_OUT_OF_RANGE
ERR_OUT_OF_RANGE
Error message
The value of "iterations" is out of range. It must be <= ${MAX_I32}. Received ${iterations} What it means
pbkdf2's argument checker (check() in ext/node/polyfills/internal/crypto/pbkdf2.ts) throws ERR_OUT_OF_RANGE when 'iterations' exceeds 2147483647 (2^31-1). iterations is first validated as a positive uint32, then explicitly capped at the signed 32-bit limit used by the native PBKDF2 implementation. Values above it cannot be passed to the underlying crypto library at all.
Source
Thrown at ext/node/polyfills/internal/crypto/pbkdf2.ts:61
const MAX_ALLOC = MathPow(2, 30) - 1;
const MAX_I32 = 2 ** 31 - 1;
function check(
password: any,
salt: any,
iterations: number,
keylen: number,
digest: string,
) {
validateString(digest, "digest");
password = getArrayBufferOrView(password, "password", "buffer");
salt = getArrayBufferOrView(salt, "salt", "buffer");
validateUint32(iterations, "iterations", true);
validateUint32(keylen, "keylen");
if (iterations > MAX_I32) {
throw new ERR_OUT_OF_RANGE("iterations", `<= ${MAX_I32}`, iterations);
}
if (keylen > MAX_I32) {
throw new ERR_OUT_OF_RANGE("keylen", `<= ${MAX_I32}`, keylen);
}
return { password, salt, iterations, keylen, digest };
}
/**
* @param iterations Needs to be higher or equal than zero
* @param keylen Needs to be higher or equal than zero but less than max allocation size (2^30)
* @param digest Algorithm to be used for encryption
*/
function pbkdf2Sync(
password: any,
salt: any,
iterations: number,View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use a realistic iteration count, e.g., 100,000-600,000 for PBKDF2-SHA256 per current OWASP guidance
- Clamp and validate iterations <= 2147483647 before calling pbkdf2
- If you genuinely need more key stretching, switch to scrypt or argon2 rather than pushing iterations past the cap
Example fix
// before const iterations = Number(cfg.iterations); // 3_000_000_000 from config crypto.pbkdf2Sync(pw, salt, iterations, 32, 'sha256'); // throws // after const iterations = Math.min(Number(cfg.iterations), 600_000); crypto.pbkdf2Sync(pw, salt, iterations, 32, 'sha256');
Defensive patterns
Strategy: validation
Validate before calling
const MAX_I32 = 2 ** 31 - 1;
if (!Number.isInteger(iterations) || iterations <= 0 || iterations > MAX_I32) {
throw new RangeError(`iterations must be an integer in (0, ${MAX_I32}]`);
}
crypto.pbkdf2Sync(password, salt, iterations, keylen, digest); Type guard
const isValidPbkdf2Iterations = (n: unknown): n is number => typeof n === 'number' && Number.isInteger(n) && n > 0 && n <= 2 ** 31 - 1;
Try / catch
try {
crypto.pbkdf2Sync(password, salt, iterations, keylen, digest);
} catch (e) {
if (e?.code === 'ERR_OUT_OF_RANGE' && /iterations/.test(e.message)) {
throw new Error(`refusing absurd iterations=${iterations}; check config`);
} else throw e;
} Prevention
- Parse iterations from config as an integer and bound-check against 2^31-1
- Store security-policy iteration counts in code review, not ad-hoc config edits
- Prefer scrypt/argon2 when more stretching is genuinely needed
When it happens
Trigger: crypto.pbkdf2Sync(password, salt, 3_000_000_000, 32, 'sha256') — any iterations value greater than MAX_I32, including via the async crypto.pbkdf2 form.
Common situations: Security-policy numbers translated with a wrong multiplier (600k read as 600,000,000); iterations parsed from config with a stray unit or extra digit; benchmark scripts cranking iteration counts to extremes.
Related errors
- PBKDF2 keys are not extractable
- Unsupported key usage for a PBKDF2 key
- ERR_CRYPTO_INVALID_DIGEST
- ERR_CRYPTO_INVALID_SCRYPT_PARAMS
- ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/b913bdb2a467ba5f.
Report an issue: GitHub.