siyuan-note/siyuan · error
unsupported encrypted envelope spec
Error message
unsupported encrypted envelope spec
What it means
Raised by EncryptionNonce when the spec byte at offset len(encryptionMagic) (4) does not equal EncryptionSpec (currently 1). The spec byte identifies the envelope format version; a mismatch means the blob is either a future/incompatible version or corrupted at that byte.
Source
Thrown at kernel/util/kdf.go:110
func Encrypt(key, plaintext []byte) ([]byte, error) {
return encryptGCM(key, plaintext, nil, "Encrypt")
}
// Decrypt 对应 Encrypt 的解密。密钥错误、格式无效或密文被篡改时返回错误。
func Decrypt(key, ciphertext []byte) ([]byte, error) {
return decryptGCM(key, ciphertext, nil, "Decrypt")
}
// EncryptionNonce 从 AES-GCM 密文信封中提取 nonce。
func EncryptionNonce(ciphertext []byte) ([]byte, error) {
if !hasEncryptionMagic(ciphertext) {
return nil, errors.New("invalid encrypted envelope magic")
}
if len(ciphertext) < encryptionEnvelopeHeaderSize {
return nil, errors.New("encrypted envelope too short")
}
if ciphertext[len(encryptionMagic)] != EncryptionSpec {
return nil, errors.New("unsupported encrypted envelope spec")
}
if ciphertext[len(encryptionMagic)+1] != encryptionAlgorithmAES256GCM {
return nil, errors.New("unsupported encrypted envelope algorithm")
}
nonceLength := int(ciphertext[len(encryptionMagic)+2])
if nonceLength == 0 || len(ciphertext) < encryptionEnvelopeHeaderSize+nonceLength {
return nil, errors.New("invalid encrypted envelope nonce length")
}
return append([]byte(nil), ciphertext[encryptionEnvelopeHeaderSize:encryptionEnvelopeHeaderSize+nonceLength]...), nil
}
// DeriveSubKey 用 HKDF-SHA256 从主 DEK 派生用途隔离的子密钥。
// 同一 (dek, purpose) 多次调用结果一致;不同 purpose 派生出相互独立的子密钥,
// 实现用途分离——.sy/assets/AV 各用独立子密钥,互不可替代,限制单点密钥泄漏的影响面。
func DeriveSubKey(dek []byte, purpose string) []byte {
// HKDF info 用 purpose 字节;salt 为 nil(DEK 本身已是高熵随机密钥,无需额外 salt)
r := hkdf.New(sha256.New, dek, nil, []byte(purpose))
out := make([]byte, 32) // AES-256View on GitHub (pinned to 251596fc0d)
Solutions
- Upgrade the kernel to a version that understands the spec byte in the blob.
- If the spec byte is unexpected due to corruption, restore from backup.
- Do not hand-edit envelope bytes; regenerate via the official crypto flow.
Defensive patterns
Strategy: validation
Validate before calling
if util.IsCiphertext(blob) && len(blob) > 4 && blob[4] != byte(util.EncryptionSpec) {
return fmt.Errorf("envelope spec %d is unsupported by this kernel", blob[4])
} Prevention
- Keep kernel and notebook formats on compatible versions.
- Do not hand-edit envelope bytes.
- Restore from backup if the spec byte looks corrupted.
When it happens
Trigger: EncryptionNonce reads a blob whose 5th byte is not 1. Happens if the blob was produced by a newer SiYuan using a higher spec, or if the byte was flipped by corruption.
Common situations: Opening a notebook created by a newer kernel version that bumped EncryptionSpec; bit-rot in the conf; an older kernel reading a newer-format envelope.
Related errors
- invalid encrypted envelope magic
- encrypted envelope too short
- unsupported encrypted envelope algorithm
- invalid encrypted envelope nonce length
- password must not be empty
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/a05ded3c8101af52.
Report an issue: GitHub.