embassy-rs/embassy · error
Input length must be a multiple of
Error message
Input length must be a multiple of {} bytes. What it means
For non-final processing the driver requires input length to be a multiple of the cipher block size (16 bytes for AES), since hardware without padding cannot consume a partial block. A non-final chunk with a remainder panics, reporting the required block size via the {} format argument.
Solutions
- Buffer input into block-aligned (16-byte) chunks; only the final chunk with last_block=true may be shorter where the mode allows.
- Use a padding/CTS mode for arbitrary-length inputs, applying padding before the final call.
- Pad the input yourself to a block multiple and track the real length for verification.
Example fix
// before
for chunk in data.chunks(1024 + 7) { ctx.payload(chunk, &mut out, false); } // unaligned
// after
for chunk in data.chunks(1024) { ctx.payload(chunk, &mut out, false); } // block-aligned Defensive patterns
Strategy: validation
Validate before calling
if !is_last && input.len() % 16 != 0 { /* stage bytes until a full 16-byte block is available */ } Prevention
- Use block-multiple read sizes in streaming code
- Keep a small staging buffer to align partial chunks
- Document block alignment requirements per mode
When it happens
Trigger: Calling payload() with last_block=false and input.len() % C::BLOCK_SIZE != 0 — e.g. a 10-byte chunk into AES.
Common situations: Reading files in arbitrary-size chunks and passing them straight to the cipher; protocol framing yielding non-aligned bodies; forgetting only the final block may be partial.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Message is too large for given IV size.
- Cannot update AAD after starting payload!
- Additional associated data must be processed first!
- The last block has already been processed!
- Output buffer length must match input length.
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/50605980a3760ddf.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/cryp/mod.rs:1423
} else if !ctx.aad_complete {
#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
{
ctx.aad_complete = true;
T::regs().cr().modify(|w| w.set_crypen(false));
T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
T::regs().cr().modify(|w| w.set_fflush(true));
T::regs().cr().modify(|w| w.set_crypen(true));
}
}
if ctx.last_block_processed {
panic!("The last block has already been processed!");
}
if input.len() > output.len() {
panic!("Output buffer length must match input length.");
}
if !last_block {
if last_block_remainder != 0 {
panic!("Input length must be a multiple of {} bytes.", C::BLOCK_SIZE);
}
}
if C::REQUIRES_PADDING {
if last_block_remainder != 0 {
panic!(
"Input must be a multiple of {} bytes in ECB and CBC modes. Consider padding or ciphertext stealing.",
C::BLOCK_SIZE
);
}
}
if last_block {
ctx.last_block_processed = true;
}
// Load data into core, block by block.
let num_full_blocks = input.len() / C::BLOCK_SIZE;
for block in 0..num_full_blocks {
let index = block * C::BLOCK_SIZE;View on GitHub (pinned to 463a07b963)