denoland/deno · error · NodeRangeError
ERR_OUT_OF_RANGE
ERR_OUT_OF_RANGE
Error message
The value of "candidate" is out of range. It must be >= 0. Received ${candidate} What it means
Thrown by Deno's node:crypto polyfill for checkPrime() (ext/node/polyfills/internal/crypto/random.ts:94) when the candidate argument is a negative BigInt. checkPrime runs probabilistic primality tests and only makes sense for non-negative integers, so any candidate < 0n is rejected before the native op is invoked. The async checkPrime and its callback are never reached; the error is thrown synchronously.
Source
Thrown at ext/node/polyfills/internal/crypto/random.ts:94
) {
if (typeof options === "function") {
callback = options;
options = {};
}
validateFunction(callback, "callback");
validateObject(options, "options");
const {
checks = 0,
} = options!;
validateInt32(checks, "options.checks", 0);
let candidateBytes: ArrayBufferView | ArrayBuffer;
if (typeof candidate === "bigint") {
if (candidate < 0) {
throw new ERR_OUT_OF_RANGE("candidate", ">= 0", candidate);
}
candidateBytes = bigintToBytes(candidate);
} else if (isAnyArrayBuffer(candidate) || isArrayBufferView(candidate)) {
const byteLength = isArrayBufferView(candidate)
? arrayBufferViewByteLength(candidate as ArrayBufferView)
: ArrayBufferPrototypeGetByteLength(candidate as ArrayBuffer);
if (byteLength > OPENSSL_BIGNUM_MAX_BYTES) {
throw new NodeError(
"ERR_OSSL_BN_BIGNUM_TOO_LONG",
"bignum too long",
);
}
candidateBytes = candidate;
} else {
throw new ERR_INVALID_ARG_TYPE(
"candidate",
[
"ArrayBuffer",View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Ensure the candidate BigInt is non-negative before calling checkPrime (mask sign with BigInt.asUintN(bitLength, value) if the value came from signed bytes).
- If the value legitimately can be negative, reject or absolute-value it in your own code first — primality of a negative number is not a meaningful query.
- Pass the number as a Buffer/Uint8Array of unsigned bytes instead of a BigInt, since only the bigint branch checks sign.
Example fix
// before
const p = maybeNegative;
crypto.checkPrime(p, (err, is) => {});
// after
const p = BigInt.asUintN(2048, maybeNegative);
if (p <= 0n) throw new RangeError('candidate must be positive');
crypto.checkPrime(p, (err, is) => {}); Defensive patterns
Strategy: validation
Validate before calling
if (typeof candidate === 'bigint' && candidate < 0n) throw new RangeError('candidate must be >= 0'); Type guard
const isPrimeCandidate = (v) => (typeof v === 'bigint' ? v >= 0n : ArrayBuffer.isView(v) || v instanceof ArrayBuffer);
Try / catch
try { crypto.checkPrime(c, cb); } catch (e) { if (e.code === 'ERR_OUT_OF_RANGE') { /* normalize candidate and retry once */ } else throw e; } Prevention
- Keep candidates as unsigned BigInts; use BigInt.asUintN when reinterpreting bytes.
- Start prime searches at 2n and only increment.
When it happens
Trigger: Calling crypto.checkPrime(-7n, cb) or crypto.checkPrime(-1n, { checks: 16 }, cb). Also hit when a computed BigInt (e.g. a subtraction or a value parsed from signed two's-complement bytes without masking) goes negative and is passed as candidate.
Common situations: Diffie-Hellman or prime-search code that derives candidates arithmetically; converting signed buffers to BigInt with BigInt.asIntN instead of BigInt.asUintN; unit tests feeding boundary values like -0n's neighbors.
Related errors
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_ARG_TYPE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/18db44ceaf4e04a0.
Report an issue: GitHub.