siyuan-note/siyuan · warning

encrypted notebook is not accessible

Error message

encrypted notebook is not accessible

What it means

Thrown by GetDEK when IsEncryptedBox(boxID) returns true but isBoxUnlockedForAccess(boxID) returns false. This means the notebook is recognized as encrypted, but the user has not yet entered the master password to unlock it (or it has been auto-locked). The DEK is not in the cachedDEKs map, so file/asset/db operations that need it cannot proceed.

Source

Thrown at kernel/model/crypto.go:1653

}

// mustEncryptionNonce 从刚刚成功生成的密文中提取 nonce。生成密文格式错误属于内部不变量被破坏,直接终止执行。
func mustEncryptionNonce(ciphertext []byte) []byte {
	nonce, err := util.EncryptionNonce(ciphertext)
	if err != nil {
		panic("extract encryption nonce failed: " + err.Error())
	}
	return nonce
}

// GetDEK 取已缓存的 DEK。返回副本,避免外部零化影响缓存。
// filesys/assets/db 加解密时调用。
func GetDEK(boxID string) ([]byte, error) {
	if !ast.IsNodeIDPattern(boxID) {
		return nil, errors.New("invalid notebook ID")
	}
	if IsEncryptedBox(boxID) && !isBoxUnlockedForAccess(boxID) {
		return nil, errors.New("encrypted notebook is not accessible")
	}
	cachedDEKsLock.RLock()
	defer cachedDEKsLock.RUnlock()
	dek, ok := cachedDEKs[boxID]
	if !ok {
		return nil, errors.New("no DEK cached for box " + boxID)
	}
	ret := make([]byte, len(dek))
	copy(ret, dek)
	return ret, nil
}

// ClearDEK 清除指定笔记本的 DEK。Unmount 单个加密笔记本时调用。
func ClearDEK(boxID string) {
	LockBox(boxID)
}

// ChangeMasterPassword 改主密码:用旧密码校验后,用新密码派生新 KEK,

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Unlock the notebook first by calling UnlockBox with the master password.
  2. If this fires during background operations after restart, ensure the user is prompted to unlock encrypted notebooks before those operations run.
  3. Check the auto-lock timeout setting (AutoLockMinutes) — if it's too short for the user's workflow, increase it.
  4. For API consumers, call getEncryptedNotebookStatus to check unlock state before attempting operations that require DEK access.
Defensive patterns

Strategy: validation

Validate before calling

// Check unlock status before accessing encrypted data:
if model.IsEncryptedBox(boxID) && !model.IsBoxUnlocked(boxID) {
    // prompt user to unlock, or skip the operation
    return
}
dek, err := model.GetDEK(boxID)

Prevention

When it happens

Trigger: Called from filesys, asset serving (api/asset.go:346,416), file operations (api/file.go:64), export (api/export.go:1170), and upload (model/upload.go:604). Fires when these internal paths try to read/write encrypted data for a notebook that is currently locked. For example: serving a thumbnail for a locked encrypted notebook, or a background sync/index touching encrypted .sy files.

Common situations: Auto-lock timer expired (AutoLockMinutes) and the notebook was locked while a background operation was in-flight. User locked the notebook manually but a plugin or sync job still tries to access its data. SiYuan restarted (DEKs don't persist across restarts) and background initialization tries to index encrypted notebooks before the user unlocks them.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/d03bb29d1e67c9f7. Report an issue: GitHub.