{"record":{"id":"92d569f98d2f73e8","repo":"jdx/mise","slug":"data-too-short-to-contain-nonce","errorCode":null,"errorMessage":"data too short to contain nonce","messagePattern":"data too short to contain nonce","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/toolset/env_cache.rs","lineNumber":43,"sourceCode":"}\n\nfn encrypt_data(data: &[u8], key: &[u8; 32]) -> Result<Vec<u8>> {\n    let cipher = ChaCha20Poly1305::new_from_slice(key)\n        .map_err(|e| eyre::eyre!(\"failed to create cipher: {}\", e))?;\n    let nonce = Nonce::generate();\n    let ciphertext = cipher\n        .encrypt(&nonce, data)\n        .map_err(|e| eyre::eyre!(\"encryption failed: {}\", e))?;\n\n    // Format: nonce || ciphertext\n    let mut result = nonce.to_vec();\n    result.extend(ciphertext);\n    Ok(result)\n}\n\nfn decrypt_data(data: &[u8], key: &[u8; 32]) -> Result<Vec<u8>> {\n    if data.len() < 12 {\n        bail!(\"data too short to contain nonce\");\n    }\n\n    let nonce =\n        Nonce::try_from(&data[..12]).map_err(|e| eyre::eyre!(\"failed to read nonce: {}\", e))?;\n    let ciphertext = &data[12..];\n\n    let cipher = ChaCha20Poly1305::new_from_slice(key)\n        .map_err(|e| eyre::eyre!(\"failed to create cipher: {}\", e))?;\n\n    let plaintext = cipher\n        .decrypt(&nonce, ciphertext)\n        .map_err(|e| eyre::eyre!(\"decryption failed: {}\", e))?;\n    Ok(plaintext)\n}\n\nfn validate_watch_files(watch_files: &[PathBuf], expected_mtimes: &[u64]) -> Result<()> {\n    if watch_files.len() != expected_mtimes.len() {\n        bail!(\"watch file count mismatch\");","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/toolset/env_cache.rs#L25-L61","documentation":"decrypt_data expects encrypted env-cache blobs in the format [12-byte nonce || ciphertext+tag] under AES-GCM with a 32-byte key. If the data is shorter than 12 bytes it cannot even contain a nonce, so decryption aborts — this guards against decrypting truncated or unencrypted data.","triggerScenarios":"Toolset env_cache load (or the encryption roundtrip test) reads a cache file whose bytes are < 12 long — a truncated/corrupted cache file, an empty file, or a file written by an incompatible/unencrypted format.","commonSituations":"Disk-full or crash mid-write leaving a truncated cache; a cache produced by a different mise version or encryption setting; manually copying/clearing cache files.","solutions":["Delete the corrupted env cache file so it is regenerated on the next load","Clear the mise cache directory (e.g. `mise cache clean` or remove the env cache location) if multiple entries are corrupt","Check for disk-full/IO issues that truncated writes; ensure the same mise version rewrites the cache"],"exampleFix":"// before\nrm $(mise cache dir)/env-cache.bin  # truncated file\n// after: next `mise env` load rewrites a valid nonce+ciphertext cache","handlingStrategy":"try-catch","validationCode":"// verify cache blob is plausibly encrypted before load\nconst buf = fs.readFileSync(cachePath);\nif (buf.length < 12 + 16) fs.rmSync(cachePath); // too short for nonce+tag; let it regenerate","typeGuard":"function isEncryptedBlob(b) { return Buffer.isBuffer(b) && b.length >= 28; } // 12 nonce + 16 GCM tag","tryCatchPattern":"// delete and rebuild cache on decrypt failure\nmatch env_cache::load(path) {\n    Err(e) if e.to_string().contains(\"data too short\") => {\n        std::fs::remove_file(path).ok();\n        env_cache::load(path).or_default()\n    }\n    r => r,\n}","preventionTips":["Guard cache writes against truncation (write to temp then rename)","Clear caches after switching mise versions or encryption settings","Treat cache decryption failure as cache-miss, not fatal, in wrappers"],"tags":["encryption","cache","aes-gcm","data-corruption"],"backgroundTag":"invalid-argument-format","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}