siyuan-note/siyuan · error
Decryption failed: incorrect key or corrupted data [box=%s]
Error message
Decryption failed: incorrect key or corrupted data [box=%s]
What it means
Thrown by ChangeMasterPassword Phase 0 when decryptBoxCrypt(id, oldKEK) fails for a specific encrypted notebook. decryptBoxCrypt tries both the conf.json BoxCrypt and the per-notebook backup; failure means the old password's KEK could not unwrap any WrappedDEK for that notebook. The message includes the box ID for diagnosis (Language(316) + ' [box=<id>]').
Source
Thrown at kernel/model/crypto.go:1730
}
newKEK := util.DeriveKey(newPassword, nc.MasterSalt, params)
defer zeroAndClear(newKEK)
newVerifier, err := util.EncryptWithAAD(newKEK, kekVerifierMagic, []byte("siyuan:kek-verifier"))
if err != nil {
return err
}
// Phase 0: 遍历所有加密笔记本(含 conf 损坏但存在备份的),预计算新 WrappedDEK(内存操作)
// 允许 entries 为空:用户可能已启用加密功能但尚未创建加密笔记本,此时仍需更新全局 verifier 和 backup。
encBoxIDs, listErr := listAllEncryptedBoxIDs()
if listErr != nil {
return fmt.Errorf("list encrypted notebooks failed: %w", listErr)
}
var entries []migrationBoxEntry
for _, id := range encBoxIDs {
dek, boxCrypt, dErr := decryptBoxCrypt(id, oldKEK)
if dErr != nil {
return errors.New(Conf.Language(316) + " [box=" + id + "]")
}
newWrapped, nErr := util.EncryptWithAAD(newKEK, dek, wrappedDEKAAD(id))
if nErr != nil {
return nErr
}
entries = append(entries, migrationBoxEntry{
BoxID: id,
NewSpec: boxEncryptionSpec,
NewWrappedDEK: newWrapped,
NewWrapNonce: mustEncryptionNonce(newWrapped),
Metadata: append([]byte(nil), boxCrypt.Metadata...),
})
}
// Phase 1: 持久化 migration manifest(崩溃后 recovery 的依据)
newParamsJSON, _ := gulu.JSON.MarshalJSON(params)
mig := &masterPasswordMigration{
OldVerifier: nc.KEKVerifier,View on GitHub (pinned to 251596fc0d)
Solutions
- Verify the old password is correct — try unlocking one of the listed encrypted notebooks with it first.
- Identify the problematic box from the [box=<id>] suffix and check if its WrappedDEK matches the current global verifier.
- If one notebook has an inconsistent WrappedDEK, restore its conf.json or backup from a device where it's consistent, let sync propagate, then retry the password change.
- If a master-password migration is pending from a previous attempt, restart SiYuan to complete recovery first.
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the old password works before starting the migration by // attempting to derive the KEK (or unlock a test notebook): // deriveKEK is internal, but you can call UnlockBox on one notebook // to validate the password, then LockBox before ChangeMasterPassword.
Try / catch
if err := model.ChangeMasterPassword(oldPassword, newPassword); err != nil {
if strings.Contains(err.Error(), "[box=") {
// specific notebook failed to decrypt with old KEK
// extract box ID, check its WrappedDEK consistency
}
} Prevention
- Verify the old password by unlocking one encrypted notebook before starting the password change.
- Ensure all notebooks are synced and have consistent WrappedDEKs before changing the password.
- Complete any pending migration (restart SiYuan) before starting a new password change.
When it happens
Trigger: Fires during ChangeMasterPassword when the old password is wrong (same KEK can't decrypt any WrappedDEK), or when a specific notebook's WrappedDEK is corrupted/belongs to a different KEK than the others. The error is returned immediately, aborting the migration before any changes are written.
Common situations: User enters the wrong old password. A notebook was encrypted under a different master password (e.g., imported from another workspace). A partial migration on another device left one notebook's WrappedDEK on the old key while the global verifier was already switched. Sync brought an inconsistent WrappedDEK for one notebook.
Related errors
- cannot change master password while encrypted notebooks are
- Master password change partially failed. Please restart SiYu
- path belongs to encrypted notebook [%s]: %s
- unsupported encrypted notebook key envelope
- encrypted notebook key envelope creation time is missing
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/ad1373379b3cb251.
Report an issue: GitHub.