siyuan-note/siyuan · critical
decrypt box [%s] failed: incorrect key or corrupted data
Error message
decrypt box [%s] failed: incorrect key or corrupted data
What it means
decryptBoxCrypt throws this after it tried the primary WrappedDEK and every alternate WrappedDEK in the backup, and none decrypted successfully under the provided KEK. It means the derived KEK is wrong (incorrect master password) or the stored ciphertext (envelope/backup) is corrupted. Unlike error 970, key material exists but cannot be decrypted.
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 8641553a1f)
Solutions
- Re-enter the master password carefully (check keyboard layout, trailing whitespace, IME state) and retry unlock
- Check whether any recent sync or restore operation overwrote conf.json or the crypt backup; restore the pre-change snapshot
- If corruption is suspected, verify the data directory is intact and use the documented recovery material (docs/ENCRYPTED-NOTEBOOK.md); never regenerate the MasterSalt
- As a last resort restore the entire workspace from backup; the DEK is unrecoverable without a valid envelope plus the correct password
Defensive patterns
Strategy: try-catch
Try / catch
// Go
dek, crypt, err := model.UnlockBox(boxID, password, boxEnc)
if err != nil && strings.Contains(err.Error(), "incorrect key or corrupted data") {
// surface a password prompt; do NOT retry with the same input in a loop
// count attempts and lock out after N failures to protect against brute force
} Prevention
- Confirm the master password once (double-entry field) before invoking unlock
- Back up conf.json and the crypt backup before password changes; test with ChangeMasterPassword paths
- Avoid mixing workspace snapshots across sync targets
- Record recovery material per docs/ENCRYPTED-NOTEBOOK.md when setting the password
When it happens
Trigger: decryptWrappedDEKWithHistory fails for the primary envelope and for all backup WrappedDEKs during UnlockBox/unlockBoxHeld, ChangeMasterPassword, or the password-change recovery test, with a KEK derived from the supplied password.
Common situations: User typed the wrong master password; Argon2id parameters or salt changed between versions; conf.json and its backup were both corrupted or tampered with; a sync conflict replaced the envelope with one wrapped under a different password.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Conf.Language(316) + " [box=" + id + "]"
- symlink resolves into encrypted notebook [%s]
- master password migration is pending
- master password migration is pending: %v
- Related operations are being processed, please try again lat
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/185f2c4f5438326f.
Report an issue: GitHub.