gchq/CyberChef · error · OperationError

IPv4 CIDR must be less than 32

Error message

IPv4 CIDR must be less than 32

What it means

Thrown by ipv4CidrRange when the CIDR prefix length is outside 0-31. The message says 'less than 32' but the guard (`cidrRange < 0 || cidrRange > 31`) also rejects /32 itself, because the mask computation `~(0xFFFFFFFF >>> 32)` is undefined for a 32-bit shift in JS (shifts are mod 32). OperationError, so it surfaces as recipe output.

Source

Thrown at src/core/lib/IP.mjs:29

import Utils from "../Utils.mjs";
import OperationError from "../errors/OperationError.mjs";

/**
 * Parses an IPv4 CIDR range (e.g. 192.168.0.0/24) and displays information about it.
 *
 * @param {RegExp} cidr
 * @param {boolean} includeNetworkInfo
 * @param {boolean} enumerateAddresses
 * @param {boolean} allowLargeList
 * @returns {string}
 */
export function ipv4CidrRange(cidr, includeNetworkInfo, enumerateAddresses, allowLargeList) {
    const network = strToIpv4(cidr[1]),
        cidrRange = parseInt(cidr[2], 10);
    let output = "";

    if (cidrRange < 0 || cidrRange > 31) {
        throw new OperationError("IPv4 CIDR must be less than 32");
    }

    const mask = ~(0xFFFFFFFF >>> cidrRange),
        ip1 = network & mask,
        ip2 = ip1 | ~mask;

    if (includeNetworkInfo) {
        output += "Network: " + ipv4ToStr(network) + "\n";
        output += "CIDR: " + cidrRange + "\n";
        output += "Mask: " + ipv4ToStr(mask) + "\n";
        output += "Range: " + ipv4ToStr(ip1) + " - " + ipv4ToStr(ip2) + "\n";
        output += "Total addresses in range: " + (((ip2 - ip1) >>> 0) + 1) + "\n\n";
    }

    if (enumerateAddresses) {
        if (cidrRange >= 16 || allowLargeList) {
            output += generateIpv4Range(ip1, ip2).join("\n");
        } else {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Use a prefix length of 0-31 for range operations.
  2. For a /32 single host, handle it as a single address outside this function.
  3. Validate the prefix is an integer in [0,31] before calling.

Example fix

// before
ipv4CidrRange(["10.0.0.0/32", "10.0.0.0", "32"], true, false, false);

// after
ipv4CidrRange(["10.0.0.0/24", "10.0.0.0", "24"], true, false, false);
Defensive patterns

Strategy: validation

Validate before calling

function assertIpv4Cidr(prefix) {
  if (!Number.isInteger(prefix) || prefix < 0 || prefix > 31) {
    throw new Error(`IPv4 CIDR prefix must be 0-31, got ${prefix}`);
  }
}
const prefix = parseInt(match[2], 10);
assertIpv4Cidr(prefix);
ipv4CidrRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList);

Type guard

const isRangeIpv4Cidr = prefix => Number.isInteger(prefix) && prefix >= 0 && prefix <= 31;

Try / catch

try {
  ipv4CidrRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList);
} catch (err) {
  if (err instanceof OperationError && /IPv4 CIDR must be less than 32/.test(err.message)) {
    // /32 or out-of-range; handle as single host or correct input
  } else throw err;
}

Prevention

When it happens

Trigger: Calling ipv4CidrRange with a regex match whose prefix group is '32' (single host), negative, or non-numeric garbage parsed by parseInt into NaN/out-of-range.

Common situations: User enters a /32 host route expecting a single-address range; typo like '/33' or '/-1'; passing an IPv4 with no prefix so parseInt yields NaN.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/0a195351c26f0fc1. Report an issue: GitHub.