siyuan-note/siyuan · error
invalid trailing encrypted asset data
Error message
invalid trailing encrypted asset data
What it means
Even after content length checks pass, the function requires the reader to be exactly at EOF (one trailing read must return io.EOF). Any extra byte after the trailer yields this error, guaranteeing the decrypted file consumed the entire encrypted stream with no appended garbage.
Source
Thrown at kernel/model/crypto.go:2497
written += int64(n)
zeroAndClear(plainChunk)
if writeErr != nil {
return "", writeErr
}
if n != len(plainChunk) {
return "", io.ErrShortWrite
}
}
var terminator uint32
if err = binary.Read(reader, binary.BigEndian, &terminator); err != nil {
return "", err
}
if terminator != 0 || written != metadata.Size {
return "", errors.New("invalid encrypted asset content length")
}
var trailing [1]byte
if _, trailingErr := io.ReadFull(reader, trailing[:]); trailingErr != io.EOF {
return "", errors.New("invalid trailing encrypted asset data")
}
return metadata.OriginalName, nil
}
// DecryptAsset 对应解密。
func DecryptAsset(boxID, diskName string, dek, ciphertext []byte) ([]byte, error) {
plaintext, _, err := DecryptAssetWithName(boxID, diskName, dek, ciphertext)
return plaintext, err
}
// notebookCryptoBackupPath 返回加密笔记本的独立 BoxCrypt 备份路径。
// 该文件在主 conf.json 丢失时用作"此笔记本是加密笔记本"的标识和降级恢复源。
// 与全局 NotebookCrypto 备份(<DataDir>/.siyuan/data-crypto-backup.json)配合使用,
// 全局备份存 MasterSalt/KEKVerifier,per-notebook 备份存 WrappedDEK/WrapNonce。
const notebookCryptoBackupFilename = "notebook-crypto-backup.json"
func notebookCryptoBackupPath(boxID string) string {
return filepath.Join(util.DataDir, boxID, ".siyuan", notebookCryptoBackupFilename)View on GitHub (pinned to 8641553a1f)
Solutions
- Inspect the bytes after the trailer and remove any appended data, then retry
- Restore a clean copy of the asset from backup or sync
- Ensure the encrypting tool and reading tool use the same format version (no extra trailer fields)
- Re-encrypt the original plaintext if the appended bytes cannot be identified
Defensive patterns
Strategy: try-catch
Try / catch
if _, err := model.DecryptAsset(box, disk, dek, ct); err != nil {
if strings.Contains(err.Error(), "trailing") {
// inspect and strip appended bytes, or restore a clean copy
return restoreCleanCopy(disk)
}
return err
} Prevention
- Never concatenate or append data to encrypted asset files
- Copy files byte-for-byte (no text-mode or encoding-converting transfers)
When it happens
Trigger: DecryptAssetToWriter reads one byte past the trailer; if io.ReadFull returns anything other than io.EOF (a byte, or an I/O error other than EOF), the error is returned. Caused by data concatenated after the encrypted asset (e.g. two files concatenated, or an appended signature/nonce).
Common situations: Backup scripts concatenating files; a writer version appending extra fields the reader doesn't know; copy/paste of files including extra bytes.
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 asset format
- symlink resolves into encrypted notebook [%s]
- master password migration is pending
- master password migration is pending: %v
- Related operations are being processed, please try again lat
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/f01addbf2f18d3f6.
Report an issue: GitHub.