{"record":{"id":"dafb4181a2339367","repo":"jdx/mise","slug":"compressed-payload-exceeds-the-size-limit","errorCode":null,"errorMessage":"compressed payload exceeds the size limit","messagePattern":"compressed payload exceeds the size limit","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/agecrypt.rs","lineNumber":161,"sourceCode":"        ));\n    }\n    Ok(bytes)\n}\n\n/// zstd-compressed, then age-encrypted for `recipients`.\npub(crate) fn encrypt_bytes(\n    plaintext: &[u8],\n    recipients: &[Box<dyn Recipient + Send>],\n) -> Result<Vec<u8>> {\n    if recipients.is_empty() {\n        bail!(\"no age recipients to encrypt for\");\n    }\n    if plaintext.len() as u64 > MAX_PLAINTEXT_BYTES {\n        bail!(\"plaintext exceeds the size limit\");\n    }\n    let compressed = zstd::encode_all(plaintext, ZSTD_COMPRESSION_LEVEL)?;\n    if compressed.len() as u64 > MAX_ENCRYPTED_BYTES {\n        bail!(\"compressed payload exceeds the size limit\");\n    }\n    let encryptor =\n        Encryptor::with_recipients(recipients.iter().map(|r| r.as_ref() as &dyn Recipient))\n            .map_err(|e| eyre!(\"creating the age encryptor: {e}\"))?;\n    let mut out = Vec::new();\n    let mut writer = encryptor.wrap_output(&mut out)?;\n    writer.write_all(&compressed)?;\n    writer.finish()?;\n    if out.len() as u64 > MAX_ENCRYPTED_BYTES {\n        bail!(\"encrypted payload exceeds the size limit\");\n    }\n    Ok(out)\n}\n\npub(crate) async fn decrypt_bytes_mode(\n    ciphertext: &[u8],\n    interactive: bool,\n) -> Result<Vec<u8>, DecryptError> {","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/agecrypt.rs#L143-L179","documentation":"After zstd compression, encrypt_bytes checks the compressed length against MAX_ENCRYPTED_BYTES. Even if the original plaintext fit, incompressible data can still exceed the ciphertext budget, so the function bails before encryption rather than producing an oversized payload.","triggerScenarios":"zstd::encode_all returns a buffer whose len() > MAX_ENCRYPTED_BYTES — encrypting already-compressed/high-entropy data near the plaintext limit.","commonSituations":"Encrypting binary blobs (images, archives) that zstd cannot shrink, plaintext just under MAX_PLAINTEXT_BYTES where the compressed form still overflows, accidentally encrypting an already-compressed file.","solutions":["Reduce the input size — split into multiple encryptions below the limit","Check whether the payload is already compressed; store it out-of-band and encrypt a reference/key instead","Trim unnecessary fields from the payload (debug data, duplicated secrets) before encrypting","Increase the limit only if your deployment explicitly supports larger encrypted payloads"],"exampleFix":"// before\nlet compressed = zstd::encode_all(&binary_blob, LEVEL)?; // still too large\nlet ct = encrypt_bytes(&binary_blob, &recipients)?;\n// after\nlet key = generate_key();\nstore_out_of_band(&binary_blob, &key)?;\nlet ct = encrypt_bytes(&key, &recipients)?;","handlingStrategy":"validation","validationCode":"// Rust: pre-check post-compression size\nlet compressed = zstd::encode_all(plaintext, 3)?;\nanyhow::ensure!(compressed.len() as u64 <= MAX_ENCRYPTED_BYTES, \"compressed payload too large\");","typeGuard":"fn compressed_fits(plaintext: &[u8], max: u64) -> std::io::Result<bool> {\n    Ok(zstd::encode_all(plaintext, 3)?.len() as u64 <= max)\n}","tryCatchPattern":"match encrypt_bytes(&data, &recipients) {\n    Err(e) if e.to_string().contains(\"compressed payload exceeds\") => {\n        eprintln!(\"data is incompressible and too large; chunk or store out-of-band\");\n    }\n    other => other,\n}","preventionTips":["Assume near-zero compression for already-compressed inputs","Keep high-entropy blobs below half the limit for safety margin","Chunk binary payloads rather than encrypting whole archives"],"tags":["age","encryption","size-limit","compression"],"backgroundTag":"payload-too-large","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}