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

  1. Shrink the input before encryption: strip or split unnecessary data so the encrypted output fits under MAX_ENCRYPTED_BYTES
  2. Store large payloads out-of-band (e.g. on disk or in object storage) and encrypt only a reference or key material
  3. Check out.len() against MAX_ENCRYPTED_BYTES before calling, or catch this error and surface a user-facing 'payload too large' message
  4. 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

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


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)