{"record":{"id":"298fa6602fd7cfbb","repo":"juicedata/juicefs","slug":"received-encrypted-text-length-is-less-than-3-the","errorCode":null,"errorMessage":"received encrypted text length is less than 3, the object is corrupted","messagePattern":"received encrypted text length is less than 3, the object is corrupted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/encrypt.go","lineNumber":260,"sourceCode":"\t}\n\n\theaderSize := 3 + len(cipherkey) + len(nonce)\n\tbuf := make([]byte, headerSize+len(plaintext)+aead.Overhead())\n\tbuf[0] = byte(len(cipherkey) >> 8)\n\tbuf[1] = byte(len(cipherkey) & 0xFF)\n\tbuf[2] = byte(len(nonce))\n\tp := buf[3:]\n\tcopy(p, cipherkey)\n\tp = p[len(cipherkey):]\n\tcopy(p, nonce)\n\tp = p[len(nonce):]\n\tciphertext := aead.Seal(p[:0], nonce, plaintext, nil)\n\treturn buf[:headerSize+len(ciphertext)], nil\n}\n\nfunc (e *dataEncryptor) Decrypt(ciphertext []byte) ([]byte, error) {\n\tif len(ciphertext) < 3 {\n\t\treturn nil, fmt.Errorf(\"received encrypted text length is less than 3, the object is corrupted\")\n\t}\n\tkeyLen := int(ciphertext[0])<<8 + int(ciphertext[1])\n\tnonceLen := int(ciphertext[2])\n\tif 3+keyLen+nonceLen >= len(ciphertext) {\n\t\treturn nil, fmt.Errorf(\"malformed ciphertext: %d %d\", keyLen, nonceLen)\n\t}\n\tciphertext = ciphertext[3:]\n\tcipherkey := ciphertext[:keyLen]\n\tnonce := ciphertext[keyLen : keyLen+nonceLen]\n\tciphertext = ciphertext[keyLen+nonceLen:]\n\n\tkey, err := e.keyEncryptor.Decrypt(cipherkey)\n\tif err != nil {\n\t\treturn nil, errors.New(\"decryt key: \" + err.Error())\n\t}\n\taead, err := e.aead(key)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/encrypt.go#L242-L278","documentation":"dataEncryptor.Decrypt expects ciphertext prefixed with a 3-byte header (2-byte encrypted key length + 1-byte nonce length). If the received buffer is shorter than 3 bytes the object cannot possibly be valid encrypted data, so it is reported as corrupted.","triggerScenarios":"Calling Read on an encrypted object whose stored content is empty or shorter than 3 bytes — e.g. the object was uploaded unencrypted, truncated, or written by a non-JuiceFS tool into the same bucket path.","commonSituations":"Reading a legacy/plain object with encryption enabled; bucket re-pointed or data partially synced; manual upload/overwrite of the object in object storage; interrupted write left a stub object.","solutions":["Verify the object was written with the same encryption settings; re-upload the object from a healthy replica with encryption enabled","Check the object size in the object store; if < 3 bytes it is corrupt — restore from backup or delete and let the client re-upload","Ensure 'juicefs sync' or garbage collection was not interrupted mid-copy; re-run the sync with --check-all","Confirm you did not switch encrypt keys/algo after the data was written; the whole volume must use consistent encryption"],"exampleFix":"// before: mixing plain and encrypted writes to the same path\ncfg.EncryptKeyPath = \"\" // some writes go unencrypted\n// after: keep encryption enabled for all writes\nkey, _ := ParseRsaPrivateKeyFromPath(\"/keys/priv.pem\", \"\")\nstore, _ := createStorage(..., key, \"aes256gcm-rsa\")","handlingStrategy":"try-catch","validationCode":"obj, _ := store.Head(key)\nif obj.Size() < 3 { /* skip or restore: object cannot be valid encrypted data */ }","typeGuard":null,"tryCatchPattern":"plain, err := enc.Decrypt(ciphertext)\nif err != nil && strings.Contains(err.Error(), \"less than 3\") {\n\t// object corrupt/unencrypted: restore from replica or re-upload\n}","preventionTips":["Never mix encrypted and unencrypted writes to the same volume/bucket prefix","Use juicefs sync --check-all periodically to detect truncated objects","Enable object-store versioning or backups for recovery","Keep encryption settings immutable after volume format"],"tags":["crypto","data-corruption","decrypt","object-storage"],"backgroundTag":"checksum-mismatch","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}