{"record":{"id":"0a09e4ea7406d1b7","repo":"juicedata/juicefs","slug":"decrypt-s-0a09e4","errorCode":null,"errorMessage":"Decrypt: %s","messagePattern":"Decrypt: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/encrypt_chunked.go","lineNumber":169,"sourceCode":"\t}()\n\n\tn, err := io.ReadFull(r.r, *chunkBuf)\n\tchunk := (*chunkBuf)[:n]\n\tif err != io.ErrUnexpectedEOF && err != nil {\n\t\treturn 0, err\n\t}\n\n\tif len(chunk) < chunkHeaderSize {\n\t\treturn 0, fmt.Errorf(\"Decrypt: truncated chunk header\")\n\t}\n\tctLen := int(binary.BigEndian.Uint32(chunk[:chunkHeaderSize]))\n\tif chunkHeaderSize+ctLen > len(chunk) {\n\t\treturn 0, fmt.Errorf(\"Decrypt: chunk data truncated: need %d, have %d\", chunkHeaderSize+ctLen, len(chunk))\n\t}\n\n\tplain, decErr := r.enc.Decrypt(chunk[chunkHeaderSize : chunkHeaderSize+ctLen])\n\tif decErr != nil {\n\t\treturn 0, fmt.Errorf(\"Decrypt: %s\", decErr)\n\t}\n\n\tif r.skip > 0 {\n\t\tskip := r.skip\n\t\tr.skip = 0\n\t\tif skip >= int64(len(plain)) {\n\t\t\treturn 0, io.EOF\n\t\t}\n\t\tplain = plain[skip:]\n\t}\n\n\tn = copy(p, plain)\n\tif n < len(plain) {\n\t\tr.buf = plain[n:]\n\t\tr.chunkBuf = chunkBuf\n\t}\n\treturn n, nil\n}","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/encrypt_chunked.go#L151-L187","documentation":"After slicing a valid chunk, the chunked reader decrypts chunk[header:header+ctLen] via the underlying dataEncryptor. Failures (bad key, corrupted AEAD data, wrong nonce) are wrapped as 'Decrypt: %s'.","triggerScenarios":"Calling Read on a chunked encrypted object whose chunk payload fails AEAD verification — typically because the volume is mounted with a different RSA key than at format time, or the chunk bytes were altered/corrupted.","commonSituations":"Wrong --encrypt-key on mount; storage-level bit rot or partial restore; mixing objects written under different encryption configurations; tampered objects in a shared bucket.","solutions":["Remount using the original encrypt key from volume format; AEAD auth failures almost always mean key mismatch","Locate the corrupt object via logs and restore/re-sync it from a healthy source","Re-run juicefs fsck/gc style checks and repair from replicas where available","Ensure all clients for the volume use identical encryption settings (key file and algo)"],"exampleFix":"// before\njuicefs mount --encrypt-algo chacha20-rsa --encrypt-key k2.pem ...\n// after: match the format-time configuration\njuicefs mount --encrypt-algo aes256gcm-rsa --encrypt-key k1.pem ...","handlingStrategy":"try-catch","validationCode":"// mount-time check: encrypt a canary object then read it back\n// failure here means wrong key/corrupt chunk — fail fast before serving traffic","typeGuard":null,"tryCatchPattern":"n, err := r.Read(buf)\nif err != nil && strings.HasPrefix(err.Error(), \"Decrypt: \") {\n\t// AEAD auth failed: wrong encrypt key or corrupted chunk\n}","preventionTips":["Store the format-time private key securely and mount only with it","After mounting, read a known canary object to verify decryptability","Keep all clients on identical encryption config","Audit bucket objects for out-of-band modifications"],"tags":["crypto","decrypt","aead","key-mismatch"],"backgroundTag":"checksum-mismatch","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}