gchq/CyberChef · error · OperationError

No padding requested but input length (${message.length} byt

Error message

No padding requested but input length (${message.length} bytes) is not a multiple of ${BLOCK_SIZE} bytes.

What it means

TEA's applyPadding at TEA.mjs:196 refuses to encrypt unaligned input when padding='NO'. TEA uses an 8-byte block (BLOCK_SIZE=8); NO padding is only valid when the message is already a block multiple, otherwise the cipher would silently truncate or misalign.

Source

Thrown at src/core/lib/TEA.mjs:196

 * @param {number[]} message
 * @param {string} padding - "NO", "PKCS5", "ZERO", "RANDOM", "BIT"
 * @returns {number[]}
 */
function applyPadding(message, padding) {
    const remainder = message.length % BLOCK_SIZE;
    if (remainder === 0 && padding !== "PKCS5") return [...message];

    const nPadding = (remainder === 0 && padding === "PKCS5") ?
        BLOCK_SIZE :
        BLOCK_SIZE - remainder;

    if (nPadding === 0) return [...message];

    const padded = [...message];

    switch (padding) {
        case "NO":
            throw new OperationError(
                `No padding requested but input length (${message.length} bytes) is not a multiple of ${BLOCK_SIZE} bytes.`
            );
        case "PKCS5":
            for (let i = 0; i < nPadding; i++) padded.push(nPadding);
            break;
        case "ZERO":
            for (let i = 0; i < nPadding; i++) padded.push(0);
            break;
        case "RANDOM":
            for (let i = 0; i < nPadding; i++) padded.push(Math.floor(Math.random() * 256));
            break;
        case "BIT":
            padded.push(0x80);
            for (let i = 1; i < nPadding; i++) padded.push(0);
            break;
        default:
            throw new OperationError(`Unknown padding type: ${padding}`);
    }

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Pre-pad the message to an 8-byte multiple yourself before encrypting with padding='NO'.
  2. Or switch padding to 'PKCS5' (or ZERO/RANDOM/BIT) to let the library handle alignment.
  3. Validate message.length % 8 === 0 at the caller boundary so the error surfaces early.

Example fix

// before
encryptWithBlockMode(msg, key, iv, "ECB", "NO"); // msg is 13 bytes
// after
const aligned = msg.concat(new Array((8 - msg.length % 8) % 8).fill(0));
encryptWithBlockMode(aligned, key, iv, "ECB", "NO");
Defensive patterns

Strategy: validation

Validate before calling

const TEA_BLOCK_SIZE = 8;
function assertTeaNoPaddingAligned(message, padding) {
  if (padding === "NO" && message.length % TEA_BLOCK_SIZE !== 0)
    throw new TypeError(
      `padding='NO' requires an 8-byte multiple; got ${message.length} bytes`);
}

Type guard

function isTeaBlockAligned(bytes) {
  return Number.isInteger(bytes.length) && bytes.length % 8 === 0;
}

Try / catch

import OperationError from "../errors/OperationError.mjs";
try {
  assertTeaNoPaddingAligned(msg, padding);
  encryptWithBlockMode(msg, key, iv, mode, padding);
} catch (e) {
  if (e instanceof OperationError && /No padding requested/.test(e.message)) {
    // pre-pad to 8 bytes or switch padding to PKCS5/ZERO/RANDOM/BIT
  } else throw e;
}

Prevention

When it happens

Trigger: applyPadding(message, 'NO', ...) called with message.length % 8 != 0. This is invoked from the encrypt path for ECB/CBC modes when the user requests no padding but supplies a non-aligned message.

Common situations: Protocol mandates no padding but the framing layer did not pre-pad to 8 bytes; toggling padding to 'NO' without aligning the payload; variable-length records fed directly into ECB.

Related errors


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