siyuan-note/siyuan · error
encrypted notebook key envelope nonce mismatch
Error message
encrypted notebook key envelope nonce mismatch
What it means
The nonce embedded in the WrappedDEK ciphertext does not equal the separately stored WrapNonce field. The two must match for the envelope to be internally consistent; a mismatch means the stored pieces were mixed across generations or tampered with.
Solutions
- Identify which operation last rewrapped the DEK (e.g. ChangeMasterPassword) and restore a conf backup from before that operation
- Ensure password-change/rotation flows complete atomically across all boxes; re-run the change from a consistent state
- Do not hand-edit WrapNonce; it must be derived from the actual WrappedDEK ciphertext
Defensive patterns
Strategy: validation
Validate before calling
n, err := util.EncryptionNonce(enc.WrappedDEK); if err == nil && !bytes.Equal(n, enc.WrapNonce) { return errors.New("envelope fields inconsistent; restore pre-rotation backup") } Try / catch
if err := unlockBox(boxID); err != nil { if strings.Contains(err.Error(), "nonce mismatch") { /* restore conf backup from before the last rewrap */ } } Prevention
- Ensure master-password changes complete atomically and are not interrupted
- Keep a conf backup immediately before any password/rotation operation
- Never mix envelope fields from different backups or notebooks
When it happens
Trigger: During unlock, validateWrappedDEKEnvelope compares util.EncryptionNonce(enc.WrappedDEK) with enc.WrapNonce using bytes.Equal; any re-wrap (password change, rotation) that updated one field but not the other triggers this.
Common situations: A partially applied master-password change that rewrote WrappedDEK but left the old WrapNonce (or vice versa); restoring conf fields from different backups; concurrent writers to the same box conf.
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 rebuild encrypted indexes
- duplicate encrypted document ID
- encrypted document is a symbolic link
- encrypted document root ID does not match filename
- encrypted notebook attribute view snapshot is plaintext
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/1225675c6c6405ea.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/crypto.go:1647
if err := validateWrappedDEKEnvelope(enc); err != nil {
return nil, err
}
return util.DecryptWithAAD(kek, enc.WrappedDEK, wrappedDEKAAD(boxID))
}
func validateWrappedDEKEnvelope(enc *conf.BoxEncryption) error {
if enc == nil || enc.Spec != boxEncryptionSpec {
return errors.New("unsupported encrypted notebook key envelope")
}
if enc.CreatedAt <= 0 {
return errors.New("encrypted notebook key envelope creation time is missing")
}
nonce, err := util.EncryptionNonce(enc.WrappedDEK)
if err != nil {
return fmt.Errorf("invalid encrypted notebook key envelope: %w", err)
}
if !bytes.Equal(nonce, enc.WrapNonce) {
return errors.New("encrypted notebook key envelope nonce mismatch")
}
return nil
}
func validateBoxEncryption(enc *conf.BoxEncryption) error {
if err := validateWrappedDEKEnvelope(enc); err != nil {
return err
}
if _, err := util.EncryptionNonce(enc.Metadata); err != nil {
return fmt.Errorf("invalid encrypted notebook metadata envelope: %w", err)
}
return nil
}
// mustEncryptionNonce 从刚刚成功生成的密文中提取 nonce。生成密文格式错误属于内部不变量被破坏,直接终止执行。
func mustEncryptionNonce(ciphertext []byte) []byte {
nonce, err := util.EncryptionNonce(ciphertext)
if err != nil {View on GitHub (pinned to 9f775e8a12)