{"record":{"id":"5d40214532b70570","repo":"juicedata/juicefs","slug":"decryt-key-s","errorCode":null,"errorMessage":"decryt key: %s","messagePattern":"decryt key: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/object/encrypt.go","lineNumber":274,"sourceCode":"}\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\n\t}\n\treturn aead.Open(ciphertext[:0], nonce, ciphertext, nil)\n}\n\n// MaxOverhead returns the maximum number of extra bytes that Encrypt can add.\n// Layout is:\n//\n//\t2 bytes wrapped-key length\n//\t1 byte nonce length\n//\twrapped encrypted data key\n//\tnonce\n//\tAEAD tag\nfunc (e *dataEncryptor) MaxOverhead() int {\n\taead, err := e.aead(make([]byte, e.keyLen))","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/encrypt.go#L256-L292","documentation":"During encrypted-object decryption, the data-key portion of the ciphertext is itself decrypted with the key encryptor (RSA); if that inner decryption fails, Decrypt wraps the underlying error as \"decryt key: ...\". The stored object cannot be read with the configured key.","triggerScenarios":"Reading an encrypted object when the RSA private key does not match the public key used to encrypt the data key, the ciphertext is truncated/corrupted, or the keyEncryptor.Decrypt fails due to wrong passphrase-derived key.","commonSituations":"Changing or losing the RSA key pair after writing encrypted data; JFS_RSA_PASSPHRASE wrong so the private key decrypts but yields a wrong key; corrupted object blocks in object storage; mixing volumes with the same bucket but different encryption keys.","solutions":["Supply the correct, original RSA private key (and JFS_RSA_PASSPHRASE) that corresponds to the key used at write time.","Read the wrapped underlying error after 'decryt key:' to identify whether it is a wrong key vs. corrupt ciphertext.","Verify object integrity in the bucket (re-upload/re-sync the affected blocks if the storage is damaged).","If keys were rotated, keep old private keys available to read historical objects."],"exampleFix":"// before\njuicefs mount sqlite3://test.db /mnt/jfs  # with wrong key.pem\n// after: mount with the original key pair used for encryption\nJFS_RSA_PASSPHRASE='orig-secret' juicefs mount -e --encrypt-key original.pem sqlite3://test.db /mnt/jfs","handlingStrategy":"try-catch","validationCode":"// verify the key decrypts its own key-envelope before mounting production\n// (round-trip a test object at setup time)\nrc, err := store.Get(ctx, testKey, 0, -1)\nif err != nil { return fmt.Errorf(\"encryption key mismatch: %w\", err) }","typeGuard":null,"tryCatchPattern":"data, err := encStore.Read(ctx, key)\nif err != nil {\n    if strings.Contains(err.Error(), \"decryt key:\") {\n        return fmt.Errorf(\"wrong or lost RSA key for this volume; restore original key/passphrase: %w\", err)\n    }\n    return err\n}","preventionTips":["Back up the RSA private key and its passphrase with the volume config — data is unrecoverable without them.","Never rotate encryption keys in place; keep old keys to read historical objects.","Do a small write/read round-trip after changing encryption settings."],"tags":["encryption","aes","rsa","decryption","data-loss"],"backgroundTag":"decryption-failed","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"}