siyuan-note/siyuan · error
encrypted envelope too short
Error message
encrypted envelope too short
What it means
EncryptionNonce found the 'SENC' magic but the buffer is shorter than the 7-byte envelope header (magic 4B + spec 1B + algorithm 1B + nonceLength 1B), so the spec/algorithm/nonce-length fields cannot be read. The input is a truncated envelope.
Solutions
- Pass the complete envelope bytes as returned by Encrypt/EncryptWithAAD (never a manual slice)
- Check the read path that produced the bytes for truncation (compare against expected envelope length)
- Restore the original file from backup/sync if stored data is corrupted
Example fix
// before nonce, err := util.EncryptionNonce(envelope[:5]) // truncated header // after nonce, err := util.EncryptionNonce(envelope) // full envelope bytes
Defensive patterns
Strategy: validation
Validate before calling
if len(data) < 7 {
return errors.New("ciphertext shorter than envelope header")
} Type guard
func isCompleteHeader(b []byte) bool { return len(b) >= 7 } Try / catch
nonce, err := util.EncryptionNonce(ciphertext)
if err != nil {
return fmt.Errorf("envelope truncated or malformed: %w", err)
} Prevention
- Read the whole file/blob; avoid partial reads for encrypted data
- Never slice envelopes manually; keep header and body together
- Verify byte counts after IO against expected envelope size
When it happens
Trigger: Calling EncryptionNonce with a byte slice of length 4-6 that starts with 'SENC' — a header that was cut off mid-read, a manually sliced envelope, or corrupted storage.
Common situations: Partial file reads, copying only part of the ciphertext, slicing the envelope into header + body and passing the wrong part, or disk corruption of stored encrypted blobs.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid encrypted envelope magic
- invalid encrypted envelope nonce length
- unsupported encrypted envelope algorithm
- Decryption failed: incorrect key or corrupted data
- unsupported encrypted envelope spec
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/336ce7e953f0e6f7.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/kdf.go:107
// Encrypt 用 AES-256-GCM 加密。每次调用生成随机 nonce,因此同一明文多次加密结果不同。
// 返回格式:magic(4B) || spec(1B) || algorithm(1B) || nonceLength(1B) || nonce || ciphertext || GCM tag(16B)。
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 {View on GitHub (pinned to 9f775e8a12)