jdx/mise · error

compressed payload exceeds the size limit

Error message

compressed payload exceeds the size limit

What it means

After zstd-compressing the plaintext, encrypt_bytes checks that the compressed buffer is at most MAX_ENCRYPTED_BYTES; if not, it bails before creating the age encryptor. This bounds the size of the payload that will be handed to age and later stored/transmitted.

Source

Thrown at src/agecrypt.rs:161

        ));
    }
    Ok(bytes)
}

/// zstd-compressed, then age-encrypted for `recipients`.
pub(crate) fn encrypt_bytes(
    plaintext: &[u8],
    recipients: &[Box<dyn Recipient + Send>],
) -> Result<Vec<u8>> {
    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> {

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Shrink or split the input so the compressed payload fits the limit.
  2. Pre-check the compressed size yourself with zstd::encode_all before calling, to fail with a better message.
  3. Store large payloads out-of-band (e.g. object storage) and encrypt only a reference/key.

Example fix

// before
let ct = encrypt_bytes(&blob, &recipients)?; // bails: compressed payload exceeds the size limit
// after
let compressed_len = zstd::encode_all(&blob[..], 0)?.len();
assert!(compressed_len as u64 <= MAX_ENCRYPTED_BYTES, "split blob before encrypting");
let ct = encrypt_bytes(&blob, &recipients)?;
Defensive patterns

Strategy: validation

Validate before calling

let compressed = zstd::encode_all(&data[..], 0)?;
assert!(compressed.len() as u64 <= MAX_ENCRYPTED_BYTES, "compressed payload too large; split input");
encrypt_bytes(&data, &recipients)?;

Type guard

fn compressed_fits(data: &[u8]) -> bool {
    zstd::encode_all(data, 0).map(|c| c.len() as u64 <= 1024u64*1024*1024).unwrap_or(false)
}

Try / catch

match encrypt_bytes(&data, &recipients) {
    Ok(ct) => use(ct),
    Err(e) if e.to_string().contains("compressed payload exceeds") => eprintln!("split or store the blob out-of-band"),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: encrypt_bytes is called with input whose zstd-compressed form (at ZSTD_COMPRESSION_LEVEL) is larger than MAX_ENCRYPTED_BYTES — typically already-compressed, incompressible data near or above the limit.

Common situations: Encrypting large binary blobs, media files, or already-compressed archives that zstd cannot shrink; oversized plugin protocol payloads.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/dafb4181a2339367. Report an issue: GitHub.