#43073·bun

crypto.pbkdf2: ERR_OUT_OF_RANGE says ">= 1 and <= 2147483647", Node says ">= 1 && <= 2147483647"

Author: robobunCreated Sep 17, 2026Updated Sep 17, 2026

crypto.pbkdf2 and crypto.pbkdf2Sync word the range of iterations and keylen differently from Node. A differential run against Node v26.3.0 found it. No user reported it.

javascript
const crypto = require("crypto");
for (const args of [["a", "b", 0, 1, "sha1"], ["a", "b", 1, -1, "sha1"]]) {
  try { crypto.pbkdf2Sync(...args); } catch (e) { console.log(e.code, "|", e.message); }
}
message
Node v26.3.0 The value of "iterations" is out of range. It must be >= 1 && <= 2147483647. Received 0
Bun 1.4.3-canary (main b64b63069c) The value of "iterations" is out of range. It must be >= 1 and <= 2147483647. Received 0
Node v26.3.0 The value of "keylen" is out of range. It must be >= 0 && <= 2147483647. Received -1
Bun 1.4.3-canary The value of "keylen" is out of range. It must be >= 0 and <= 2147483647. Received -1

Node validates both arguments with validateInt32, which writes >= ${min} && <= ${max}. The and form is the wording of Node's Buffer and zlib bounds errors.

The cause is in src/runtime/crypto/PBKDF2.rs. Both checks call throw_range_error with RangeErrorOptions { min, max }, and the shared Rust formatter writes >= min and <= max for that form. fd_jsc.rs and node_crypto_binding.rs pass the range as msg (>= a && <= b) where Node uses a validator, and #40737 does the same for validators.rs. #40737 does not touch PBKDF2.rs.

test/js/node/crypto/pbkdf2.test.ts (lines 132 and 215) pins the and form for keylen, so a fix has to update those two expectations.