denoland/deno · error · Error

Output length is invalid for , which does not support XOF

Error message

Output length ${outputLength} is invalid for ${algoLower}, which does not support XOF

What it means

crypto.hash() supports outputLength only for XOF algorithms ('shake128', 'shake256'). For any other algorithm, outputLength must equal the native digest size, or a plain Error is thrown. This error has no code property.

Solutions

  1. Omit outputLength for fixed-size algorithms such as sha256 and sha512.
  2. Switch to 'shake128' or 'shake256' when you need variable output length.
  3. If the field must be present, match the digest size: 32 for sha256, 64 for sha512.

Example fix

// before
crypto.hash('sha256', data, { outputLength: 16 });

// after
crypto.hash('shake128', data, { outputLength: 16 });
Defensive patterns

Strategy: validation

Validate before calling

const XOF = new Set(['shake128', 'shake256']);
const algo = 'sha256';
const opts = XOF.has(algo.toLowerCase()) ? { outputLength: 16 } : {};

Type guard

function isXof(algo: string): boolean { const a = algo.toLowerCase(); return a === 'shake128' || a === 'shake256'; }

Prevention

When it happens

Trigger: crypto.hash('sha256', data, { outputLength: 16 }) with a truncated length. Using one options object across all algorithms and leaving outputLength set. Assuming sha2 supports truncation like SHAKE.

Common situations: A shared helper written for SHAKE reuse with fixed-width hashes. Code migrated from a library where arbitrary digest truncation was allowed. outputLength left over from a test fixture.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/1ebd0331dc2960e4. Report an issue: GitHub.

Appendix: source

Thrown at ext/node/polyfills/crypto.ts:187

      // normalizeEncoding() doesn't handle 'buffer'.
      if (StringPrototypeToLowerCase(outputEncoding) === "buffer") {
        normalized = "buffer";
      } else {
        throw new ERR_INVALID_ARG_VALUE("outputEncoding", outputEncoding);
      }
    }
  }

  const algoLower = StringPrototypeToLowerCase(algorithm);
  const isXof = algoLower === "shake128" || algoLower === "shake256";

  if (outputLength != null && !isXof) {
    // For non-XOF hashes, outputLength must match the algorithm's digest size.
    const testHash = createHash(algorithm);
    testHash.update("");
    const expectedLen = testHash.digest().length;
    if (outputLength !== expectedLen) {
      throw new Error(
        `Output length ${outputLength} is invalid for ${algoLower}, which does not support XOF`,
      );
    }
  }

  const h = createHash(
    algorithm,
    outputLength != null ? { outputLength } : undefined,
  );
  h.update(data);

  if (outputLength === 0) {
    return normalized === "buffer" ? globalThis.Buffer.alloc(0) : "";
  }

  return h.digest(outputEncoding);
}

View on GitHub (pinned to 9ad36f7a2c)