siyuan-note/siyuan · error
notebook crypto backup is incomplete or corrupted
Error message
notebook crypto backup is incomplete or corrupted
What it means
The backup file passed the spec check but notebookCryptoConfigurationComplete reports that required crypto fields are missing. The library treats this as a corrupted or tampered backup and refuses to use it for key derivation or restore, protecting against silently restoring broken encryption state.
Source
Thrown at kernel/model/crypto.go:497
// loadNotebookCryptoBackup 从 DataDir 读取 NotebookCrypto 备份。文件不存在返回 (nil, nil)。
func loadNotebookCryptoBackup() (*conf.NotebookCrypto, error) {
data, err := filelock.ReadFile(dataCryptoBackupPath())
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}
nc := &conf.NotebookCrypto{}
if err := json.Unmarshal(data, nc); err != nil {
return nil, err
}
if nc.Spec != conf.CurrentNotebookCryptoSpec {
return nil, fmt.Errorf("unsupported notebook crypto backup spec [%d]", nc.Spec)
}
if !notebookCryptoConfigurationComplete(nc) {
return nil, errors.New("notebook crypto backup is incomplete or corrupted")
}
return nc, nil
}
// removeNotebookCryptoBackup 删除备份文件(禁用加密功能时调用)。文件不存在视为成功。
func removeNotebookCryptoBackup() {
if err := os.Remove(dataCryptoBackupPath()); err != nil && !os.IsNotExist(err) {
logging.LogErrorf("remove notebook crypto backup failed: %s", err)
}
}
// masterPasswordMigration 记录改密迁移的完整状态,用于崩溃后恢复。
type masterPasswordMigration struct {
OldVerifier []byte `json:"oldVerifier"`
NewVerifier []byte `json:"newVerifier"`
NewVerifierNonce []byte `json:"newVerifierNonce"`
NewKDFParams json.RawMessage `json:"newKDFParams"`
NewHistoryKEKs [][]byte `json:"newHistoryKEKs,omitempty"`View on GitHub (pinned to 8641553a1f)
Solutions
- Restore the backup file from a verified copy (file-level restore or another machine's backup)
- Delete the corrupt backup and re-run the master password / KEK setup to generate a fresh complete backup
- Verify the backup file parses to a fully populated NotebookCrypto struct before relying on it
- If recovery is impossible, use the documented master password recovery flow rather than forcing the corrupt backup
Example fix
// before: trusting a truncated backup
nc, err := loadNotebookCryptoBackup() // incomplete
// after: keep verified copies
if err := verifyBackupIntegrity(backupPath); err != nil {
restoreFromVerifiedCopy(backupPath)
}
nc, err := loadNotebookCryptoBackup() Defensive patterns
Strategy: fallback
Validate before calling
var nc conf.NotebookCrypto
if err := json.Unmarshal(raw, &nc); err != nil {
return fmt.Errorf("corrupt backup: %w", err)
}
if !notebookCryptoConfigurationComplete(&nc) {
return fmt.Errorf("backup incomplete: refuse to use")
} Try / catch
nc, err := loadNotebookCryptoBackup()
if err != nil {
// fall back to the documented recovery flow; never force the corrupt backup
if restoreErr := restoreBackupFromVerifiedCopy(); restoreErr != nil {
return fmt.Errorf("no valid backup available: %w", restoreErr)
}
nc, err = loadNotebookCryptoBackup()
} Prevention
- Keep at least two verified copies of the crypto backup
- Verify backup integrity (complete config check) after every write
- Take a file-level backup before upgrading or migrating the workspace
- Never manually trim fields from the backup JSON
When it happens
Trigger: loadNotebookCryptoBackup reads a backup whose Spec matches but is missing mandatory fields (empty WrappedDEK, salt, KEKMAC, etc.) — via restoreNotebookCryptoConfigFromBackup, deriveNotebookCryptoBackupCandidate, or deriveKEK.
Common situations: Truncated backup file after a crash, manual edits removing fields, a backup written by a buggy older build, or file corruption on disk.
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
- cannot write incomplete notebook crypto backup
- unsupported notebook crypto backup spec [%d]
- enable encrypted notebook failed: failed to persist key back
- master password migration is pending
- master password migration is pending: Master password change
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/2e353499b43bb13f.
Report an issue: GitHub.