siyuan-note/siyuan · error

invalid encrypted notebook key envelope: %w

Error message

invalid encrypted notebook key envelope: %w

What it means

Thrown by validateWrappedDEKEnvelope when util.EncryptionNonce(enc.WrappedDEK) returns an error. EncryptionNonce parses the SENC envelope header (magic 'SENC' + spec byte + algorithm byte + nonce-length byte) and extracts the nonce. Failure means the WrappedDEK bytes don't conform to this binary envelope format at all.

Source

Thrown at kernel/model/crypto.go:1619

}

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 251596fc0d)

Solutions

  1. Restore conf.json from a DataDir backup with a valid WrappedDEK envelope.
  2. Restore the per-notebook crypt backup.
  3. Inspect the wrapped error message (the %w) to identify the specific envelope defect: 'invalid encrypted envelope magic' means the bytes aren't SENC at all; 'too short' means truncation; 'unsupported spec' means a version mismatch.
  4. If migrating programmatically, ensure WrappedDEK is the raw output of util.EncryptWithAAD, not a re-encoded form.
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the WrappedDEK envelope format:
boxCrypt, _ := model.GetBoxEncryption(boxID)
if _, err := util.EncryptionNonce(boxCrypt.WrappedDEK); err != nil {
    // WrappedDEK is not a valid SENC envelope — restore from backup
}

Prevention

When it happens

Trigger: Fires when WrappedDEK is not a valid SENC envelope: missing magic header, too short, wrong spec/algorithm byte, or invalid nonce-length. Reached during unlock and ChangeMasterPassword via decryptWrappedDEK. The wrapped %w error carries the specific envelope-parse failure (e.g., 'invalid encrypted envelope magic', 'encrypted envelope too short').

Common situations: WrappedDEK was stored as a base64 string instead of raw bytes (or vice versa) due to a serialization mismatch. conf.json was partially overwritten or truncated. A sync tool corrupted the binary field. A third-party plugin wrote a non-envelope value into WrappedDEK.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/921dc7b35dbd8835. Report an issue: GitHub.