siyuan-note/siyuan · error
encrypt notebook metadata failed
Error message
encrypt notebook metadata failed: %w
What it means
During enable-encryption, after deriving the DEK and building the BoxCrypt envelope, the notebook's own metadata (conf.json) is encrypted with encryptBoxMetadata(id, boxConf, dek). If that encryption/write step fails, this wrapped error reports it with the underlying cause. Without encrypted metadata the notebook would be half-converted, so the operation aborts before saving the box conf.
Solutions
- Read the wrapped cause in the kernel log to see whether it is a write or cipher error, and fix that root cause (permissions, disk space)
- Retry the enable-encryption operation after freeing space / fixing permissions
- Check no external sync/backup process is holding files under data/<box>/ during conversion
Example fix
// before $ siyuan --enable-encryption encrypt notebook metadata failed: open data/<box>/conf.json: permission denied // after sudo chown -R $USER:$USER data/<box>/ $ siyuan --enable-encryption # succeeds
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the notebook data dir is writable before converting
const fs = require("fs");
fs.accessSync(path.join(workspace, "data", boxID), fs.constants.W_OK); Try / catch
try {
await enableNotebookEncryption(boxID, password);
} catch (e) {
if (String(e.message).includes("encrypt notebook metadata failed")) {
logRootCause(e); // wrapped %w cause reveals write/cipher error
fixPermissionsOrDisk();
}
} Prevention
- Pause cloud-sync/backup clients during notebook conversion
- Keep adequate free disk space before enabling encryption
- Run the kernel under a user with write access to data/
When it happens
Trigger: encryptBoxMetadata returns an error — e.g. failure serializing the box conf, failure writing the encrypted metadata file to data/<box>/, or filesystem errors (permissions, disk full) while replacing the plaintext conf with its encrypted form.
Common situations: Workspace directory made read-only by another process; disk quota/full disk during conversion; file lock contention from sync clients watching data/; encryption library failure due to malformed KDF output.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- accessing assets in encrypted notebook
- enable encrypted notebook failed: failed to persist key…
- encrypted document is a symbolic link
- encrypted index has no compatibility metadata
- encrypted notebook key envelope creation time is missing
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/5d2e1dff8e796284.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/crypto.go:2655
defer func() {
if err != nil {
setEncryptedBoxState(createdBoxID, EncryptedBoxStateError)
cleanupFailedEncryptedBox(createdBoxID)
id = ""
}
}()
enc, dek, err := WrapNewDEK(id, kek)
if err != nil {
return "", err
}
box := &Box{ID: id}
boxConf := box.GetConf()
boxConf.Encrypted = true
boxConf.BoxCrypt = enc
if err = encryptBoxMetadata(id, boxConf, dek); err != nil {
return "", fmt.Errorf("encrypt notebook metadata failed: %w", err)
}
if err = box.SaveConf(boxConf); err != nil {
return "", fmt.Errorf("save encrypted notebook conf failed: %w", err)
}
if err = writeNotebookCryptBackup(id, enc); err != nil {
return "", fmt.Errorf("write notebook crypt backup failed: %w", err)
}
// 回读校验加密配置已落盘,避免写失败后按普通笔记本处理
verifyConf := box.GetConf()
if verifyConf == nil || !verifyConf.Encrypted || verifyConf.BoxCrypt == nil {
err = errors.New("encrypted notebook metadata verification failed after write")
return "", err
}
markRuntimeEncryptedBox(id)
invalidateEncryptedPublishAccessCache()
// 复用刚派生的 DEK 直接开 db + 缓存,省去再次 Argon2id 解锁
cachedDEKsLock.Lock()View on GitHub (pinned to 8641553a1f)