siyuan-note/siyuan · error
read notebook crypt backup failed: %w
Error message
read notebook crypt backup failed: %w
What it means
This error wraps a lower-level failure while reading the notebook's BoxCrypt backup file (the JSON envelope that stores the encrypted-notebook key backup). It is produced by readBoxEncryptionFile when filelock.ReadFile fails, preserving the underlying cause via %w. It means the backup file exists (or was expected) but could not be read from disk.
Source
Thrown at kernel/model/crypto.go:2557
}
// readNotebookCryptBackup 读取加密笔记本的 BoxCrypt 备份。
// 备份文件不存在时返回 (nil, nil),调用方据此区分"非加密笔记本"和"备份不存在"。
func readNotebookCryptBackup(boxID string) (*conf.BoxEncryption, error) {
if !ast.IsNodeIDPattern(boxID) {
return nil, errors.New("invalid notebook ID")
}
backupPath := notebookCryptoBackupPath(boxID)
if !filelock.IsExist(backupPath) {
return nil, nil
}
return readBoxEncryptionFile(backupPath)
}
func readBoxEncryptionFile(backupPath string) (*conf.BoxEncryption, error) {
data, err := filelock.ReadFile(backupPath)
if err != nil {
return nil, fmt.Errorf("read notebook crypt backup failed: %w", err)
}
var crypt conf.BoxEncryption
if err = gulu.JSON.UnmarshalJSON(data, &crypt); err != nil {
return nil, fmt.Errorf("unmarshal notebook crypt backup failed: %w", err)
}
if err = validateBoxEncryption(&crypt); err != nil {
return nil, err
}
return &crypt, nil
}
// copyAssetDecryptIfEncrypted 把 srcPath 的 asset 复制到 destPath。
// 若 srcPath 在已解锁的加密笔记本下,读密文→解密→写明文到 destPath(导出目录);
// 否则走 filelock.Copy 原路径(字节级复制,密文/明文均可)。
func copyAssetDecryptIfEncrypted(srcPath, destPath string) error {
if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil {
return err
}View on GitHub (pinned to 8641553a1f)
Solutions
- Check OS permissions/ownership of <workspace>/data/<notebook>/.siyuan/ crypt backup file and fix with chown/chmod or icacls
- Close other processes (backup/antivirus/sync tools) locking the file and retry
- Check disk health (dmesg/Event Viewer) and free space; restore the file from backup if it is truncated or unreadable
- Re-run the kernel as the same user that owns the workspace
Example fix
// before (OS level) cat data/20240101120000-abcd/.siyuan/crypt.json # permission denied // after sudo chown -R $USER:$USER data/20240101120000-abcd/.siyuan/ cat data/20240101120000-abcd/.siyuan/crypt.json # works
Defensive patterns
Strategy: retry
Validate before calling
// pre-check readability
const fs = require("fs");
if (!fs.accessSync(backupPath, fs.constants.R_OK)) { /* proceed */ } Try / catch
try {
await callKernel();
} catch (e) {
if (String(e.message).includes("read notebook crypt backup failed")) {
// check file permissions / disk, then retry after fixing
}
} Prevention
- Run the kernel as the user who owns the workspace directory
- Exclude workspace data/ from antivirus real-time locking where possible
- Monitor disk health and free space
When it happens
Trigger: readNotebookCryptBackup finds notebookCryptoBackupPath(boxID) exists, then readBoxEncryptionFile calls filelock.ReadFile(backupPath) and the OS read fails — permission problems, the file vanishing between the IsExist check and the read, disk I/O errors, or a locked file on Windows.
Common situations: Running SiYuan as a different user than the one who owns the workspace data; antivirus or backup software holding the file; workspace moved across machines/users with mismatched ownership; failing disk.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- read session file failed: %w
- create session dir failed: %w
- save session file failed: %w
- write data [%s] failed: %s
- read AI editor actions failed: %w
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/752b74b56f7c9421.
Report an issue: GitHub.