siyuan-note/siyuan · error
decrypt box [ ] failed: incorrect key or corrupted data
Error message
decrypt box [%s] failed: incorrect key or corrupted data
What it means
decryptBoxCrypt returns this error after both the primary WrappedDEK and any differing backup WrappedDEK fail to decrypt with the supplied KEK. It means the derived key does not match the notebook's key wrapping, or the wrapped key data is corrupted. This is the generic 'wrong password or damaged key material' outcome of the per-notebook unlock pipeline.
Solutions
- Retry with the correct current master password (each attempt costs ~1s Argon2id)
- If a password change was interrupted, complete the migration with the old or new password as appropriate so KEK and WrappedDEK generations match
- Restore the notebook's conf.json and crypto backup from a known-good backup/sync peer
- If the password is truly lost, the notebook data is unrecoverable by design; restore from an unencrypted snapshot
Example fix
// before
err := model.UnlockBox(boxID, typedPassword, boxEnc)
// treated as fatal, box marked error
// after
if err != nil && strings.Contains(err.Error(), "incorrect key or corrupted data") {
// prompt user to re-enter password; do not permanently mark state error on first failure
return retryUnlockWithPrompt(boxID)
} Defensive patterns
Strategy: try-catch
Try / catch
if err := model.UnlockBox(boxID, password, boxEnc); err != nil {
if strings.Contains(err.Error(), "incorrect key or corrupted data") {
// treat as wrong-password: prompt retry, cap attempts
}
} Prevention
- Prompt users to confirm the master password before password changes
- Complete password migrations without interruption
- Keep conf.json and crypto backup in sync across peers
- Log decryptBoxCrypt failures with the box ID for diagnosis
When it happens
Trigger: UnlockBox/UnlockAndMountBox with a wrong master password; ChangeMasterPassword racing an incomplete migration; WrappedDEK or backup WrappedDEK corrupted (bit rot, manual edit, bad sync); KEK derived from an older password while notebooks were already re-wrapped.
Common situations: User forgot/misspelled the master password; workspace synced mid-password-change so conf and backup hold WrappedDEKs from different password generations; history KEKs are out of sync so decryptWrappedDEKWithHistory cannot unwrap.
Related errors
- Conf.Language(316) + " [box=" + id + "]"
- encrypted notebook has no valid key material
- invalid historical notebook encryption key
- no encrypted key material for box
- no encrypted key material for box
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/185f2c4f5438326f.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/crypto.go:1355
dek, err = decryptWrappedDEKWithHistory(boxID, backup, kek, nc)
if err == nil {
// backup 解密成功:修复 conf + 刷新 backup
box := &Box{ID: boxID}
boxConf := box.GetConf()
boxConf.Encrypted = true
boxConf.BoxCrypt = backup
if saveErr := box.SaveConf(boxConf); saveErr != nil {
logging.LogWarnf("fix encrypted box conf from backup [%s] failed: %s", boxID, saveErr)
}
if needWriteNotebookCryptBackup(boxID, backup) {
if writeErr := writeNotebookCryptBackup(boxID, backup); writeErr != nil {
logging.LogWarnf("refresh notebook crypt backup [%s] failed: %s", boxID, writeErr)
}
}
return dek, backup, nil
}
}
return nil, nil, fmt.Errorf("decrypt box [%s] failed: incorrect key or corrupted data", boxID)
}
// UnlockBox 用主密码派生 KEK,解出该笔记本的 DEK 并缓存。KEK 用完即弃,不全局缓存。
// 每次调用都跑一次 Argon2id(约 1 秒),严格满足"每笔记本单独解锁"语义。
func UnlockBox(boxID string, password string, boxEnc *conf.BoxEncryption) (err error) {
invalidateEncryptedPublishAccessCache()
if !ast.IsNodeIDPattern(boxID) {
return errors.New("invalid notebook ID")
}
// 全局配置锁先于笔记本生命周期锁获取(设计 §17 锁顺序约定),避免与持子系统锁后回取配置锁的路径死锁。
// notebookCryptoMu 持锁期间调用的 deriveKEK/conf 修复只申请 Conf.m/cachedDEKsLock,不回取 box 生命周期锁。
notebookCryptoMu.Lock()
defer notebookCryptoMu.Unlock()
releaseTransition := holdEncryptedBoxTransition(boxID)
defer releaseTransition()
return unlockBoxHeld(boxID, password, boxEnc)
}View on GitHub (pinned to 9f775e8a12)