jdx/mise · error
encrypted payload exceeds the size limit
Error message
encrypted payload exceeds the size limit
What it means
agecrypt refuses to return an encrypted payload larger than MAX_ENCRYPTED_BYTES. After encrypting (and compressing) the input bytes, the resulting ciphertext is measured; if it exceeds the configured limit the whole encryption is discarded and the error is thrown. This guards against unexpectedly large or incompressible inputs blowing up storage/protocol message limits.
Solutions
- Shrink the input before encryption: strip or split unnecessary data so the encrypted output fits under MAX_ENCRYPTED_BYTES
- Store large payloads out-of-band (e.g. on disk or in object storage) and encrypt only a reference or key material
- Check out.len() against MAX_ENCRYPTED_BYTES before calling, or catch this error and surface a user-facing 'payload too large' message
- If the limit is legitimately too low for your use case, propose raising MAX_ENCRYPTED_BYTES upstream rather than bypassing the check
Example fix
// before
let blob = std::fs::read("huge-dump.bin")?;
let ct = encrypt_bytes(&blob, recipients).await?; // bails: encrypted payload exceeds the size limit
// after
let blob = std::fs::read("huge-dump.bin")?;
if blob.len() as u64 > MAX_ENCRYPTED_BYTES {
anyhow::bail!("input too large to encrypt inline; store it externally");
}
let ct = encrypt_bytes(&blob, recipients).await?; Defensive patterns
Strategy: validation
Validate before calling
if (input.len() as u64 > MAX_ENCRYPTED_BYTES) {
return Err(anyhow!("input {} bytes exceeds encrypt limit {}", input.len(), MAX_ENCRYPTED_BYTES));
} Try / catch
match encrypt_bytes(&data, &recipients).await {
Ok(ct) => use_ciphertext(ct),
Err(e) if e.to_string().contains("exceeds the size limit") => handle_oversized_payload(),
Err(e) => return Err(e),
} Prevention
- Estimate worst-case ciphertext size (age overhead ~ a few hundred bytes plus input) before encrypting
- Compress data yourself first and measure; already-compressed data won't shrink
- Keep large blobs out of the encrypted protocol payload; encrypt references/keys instead
- Add a unit test asserting representative payloads stay under MAX_ENCRYPTED_BYTES
When it happens
Trigger: Calling encrypt_bytes with input whose compressed-then-age-encrypted output exceeds MAX_ENCRYPTED_BYTES. Common with large binaries or already-compressed data (images, archives, videos) where compression gains nothing and the payload stays oversized.
Common situations: Embedding a large file into the plugin protocol payload; encrypting secrets that include an accidentally-inlined blob; data that grew after a format change so the old size assumption no longer holds.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- compressed payload exceeds the size limit
- encrypted file exceeds the size limit
- object exceeds the encrypted content size limit
- plaintext exceeds the size limit
- cannot encrypt non-file
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/74d150f78cd0e38e.
Report an issue: GitHub.
Appendix: source
Thrown at src/agecrypt.rs:171
if recipients.is_empty() {
bail!("no age recipients to encrypt for");
}
if plaintext.len() as u64 > MAX_PLAINTEXT_BYTES {
bail!("plaintext exceeds the size limit");
}
let compressed = zstd::encode_all(plaintext, ZSTD_COMPRESSION_LEVEL)?;
if compressed.len() as u64 > MAX_ENCRYPTED_BYTES {
bail!("compressed payload exceeds the size limit");
}
let encryptor =
Encryptor::with_recipients(recipients.iter().map(|r| r.as_ref() as &dyn Recipient))
.map_err(|e| eyre!("creating the age encryptor: {e}"))?;
let mut out = Vec::new();
let mut writer = encryptor.wrap_output(&mut out)?;
writer.write_all(&compressed)?;
writer.finish()?;
if out.len() as u64 > MAX_ENCRYPTED_BYTES {
bail!("encrypted payload exceeds the size limit");
}
Ok(out)
}
pub(crate) async fn decrypt_bytes_mode(
ciphertext: &[u8],
interactive: bool,
) -> Result<Vec<u8>, DecryptError> {
if ciphertext.len() as u64 > MAX_ENCRYPTED_BYTES {
return Err(DecryptError::Corrupt(
"encrypted payload exceeds the size limit".into(),
));
}
let loaded = load_identities(interactive).await;
if loaded.identities.is_empty() {
if loaded.plugins > 0 {
return Err(DecryptError::Failed { error: "hardware identity requires an interactive restore with its age plugin installed".into(), hint: String::new() });
}View on GitHub (pinned to 533346cc37)