siyuan-note/siyuan · error

invalid encrypted notebook key envelope

Error message

invalid encrypted notebook key envelope: %w

What it means

The WrappedDEK ciphertext could not be parsed by util.EncryptionNonce — i.e. the wrapped-DEK blob is not in the expected encrypted format (nonce+payload). The underlying parse error is wrapped with this prefix for context. This indicates the stored envelope payload is malformed, not merely stale.

Solutions

  1. Read the wrapped %w cause to determine whether the payload was empty or badly framed
  2. Restore BoxEncryption.WrappedDEK from a backup of the notebook conf
  3. If a sync conflict produced partial files, resolve in favor of the kernel-written conf
  4. Never regenerate MasterSalt or hand-craft WrappedDEK; recovery must go through documented key-recovery material
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := util.EncryptionNonce(enc.WrappedDEK); err != nil { return fmt.Errorf("wrapped DEK malformed, restore backup: %w", err) }

Try / catch

if err := unlockBox(boxID); err != nil { var cause string; if strings.Contains(err.Error(), "invalid encrypted notebook key envelope") { cause = errors.Unwrap(err).Error() /* inspect and restore */ } }

Prevention

When it happens

Trigger: Enc.BoxEncryption.WrappedDEK is empty, truncated, base64/corrupted, or written by an incompatible format; util.EncryptionNonce returns an error during validateWrappedDEKEnvelope.

Common situations: Incomplete file write (power loss/sync conflict) of notebook conf; copying only part of the envelope between workspaces; data corrupted by editing the config as plain text.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/921dc7b35dbd8835. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/crypto.go:1644

}

func decryptWrappedDEK(boxID string, enc *conf.BoxEncryption, kek []byte) ([]byte, error) {
	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。生成密文格式错误属于内部不变量被破坏,直接终止执行。

View on GitHub (pinned to 9f775e8a12)