gchq/CyberChef · error · OperationError
Invalid BIT padding.
Error message
Invalid BIT padding.
What it means
TEA's removePadding BIT case at TEA.mjs:250. BIT padding marks the start of padding with a 0x80 byte followed by zero bytes; walking backwards, the first non-zero byte encountered must be the 0x80 sentinel. This throw fires when a non-zero, non-0x80 byte is found before the sentinel — meaning the tail is not a well-formed BIT pad.
Source
Thrown at src/core/lib/TEA.mjs:250
return message;
case "PKCS5": {
const padByte = message[message.length - 1];
if (padByte > 0 && padByte <= BLOCK_SIZE) {
for (let i = 0; i < padByte; i++) {
if (message[message.length - 1 - i] !== padByte) {
throw new OperationError("Invalid PKCS#5 padding.");
}
}
return message.slice(0, message.length - padByte);
}
throw new OperationError("Invalid PKCS#5 padding.");
}
case "BIT": {
for (let i = message.length - 1; i >= 0; i--) {
if (message[i] === 0x80) return message.slice(0, i);
if (message[i] !== 0) throw new OperationError("Invalid BIT padding.");
}
throw new OperationError("Invalid BIT padding.");
}
default:
throw new OperationError(`Unknown padding type: ${padding}`);
}
}
/**
* Encrypt with block cipher modes
*
* @param {number[]} message - Plaintext bytes
* @param {number[]} key - 16-byte key
* @param {number[]} iv - 8-byte IV (ignored for ECB)
* @param {string} mode - "ECB", "CBC", "CFB", "OFB", "CTR"
* @param {string} padding - "PKCS5", "NO", "ZERO", "RANDOM", "BIT"
* @param {Function} encryptBlockFn - Block encrypt functionView on GitHub (pinned to 4290ea7539)
Solutions
- Confirm the key and IV match the encrypt side.
- Verify the encrypt-time padding was 'BIT'.
- Decrypt with 'NO' padding and inspect the tail bytes to identify the actual scheme.
Example fix
// before const pt = decryptWithBlockMode(ct, key, iv, "CBC", "BIT"); // after: data was PKCS5-padded const pt = decryptWithBlockMode(ct, key, iv, "CBC", "PKCS5");
Defensive patterns
Strategy: validation
Validate before calling
function looksLikeValidBitPad(plain) {
let sawSentinel = false;
for (let i = plain.length - 1; i >= 0; i--) {
const b = plain[i];
if (b === 0x80) { sawSentinel = true; break; }
if (b !== 0) return false;
}
return sawSentinel;
} Type guard
function isWellFormedBitPad(plain) {
let sawSentinel = false;
for (let i = plain.length - 1; i >= 0; i--) {
const b = plain[i];
if (b === 0x80) { sawSentinel = true; break; }
if (b !== 0) return false;
}
return sawSentinel;
} Try / catch
import OperationError from "../errors/OperationError.mjs";
try {
const pt = decryptWithBlockMode(ct, key, iv, mode, "BIT");
} catch (e) {
if (e instanceof OperationError && /Invalid BIT padding/.test(e.message)) {
// wrong key/IV or padding-scheme mismatch; do not return partial plaintext
} else throw e;
} Prevention
- Match encrypt and decrypt padding literals exactly.
- Avoid BIT padding for binary payloads that may contain 0x80 in-band.
- Treat BIT padding failure as a wrong-key signal.
When it happens
Trigger: Decryption with padding='BIT' where the trailing bytes contain a non-zero, non-0x80 value before the 0x80 sentinel is reached. Causes: wrong key producing random plaintext in the tail; partial corruption of the last block; encryptor used a different padding scheme but decryptor expects BIT.
Common situations: Key/IV mismatch; encrypt/decrypt padding scheme mismatch; bit-flip in the last ciphertext block producing a random tail.
Related errors
- Invalid PKCS#5 padding.
- No padding requested but input length (${message.length} byt
- Unknown padding type: ${padding}
- Invalid PKCS#7 padding.
- Invalid PKCS#5 padding.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/b54f7880356e4a5f.
Report an issue: GitHub.