siyuan-note/siyuan · error

encrypted notebook is not accessible

Error message

encrypted notebook is not accessible

What it means

The notebook is encrypted but is not currently unlocked for access (isBoxUnlockedForAccess returns false), so its DEK cannot be handed out. This is an access-control check: DEKs for locked encrypted notebooks must never leave the cache, protecting data from unauthorized decryption.

Solutions

  1. Unlock the notebook first via the normal unlock flow (prompt the user for the master password), then retry the operation
  2. Reorder logic to skip encrypted-but-locked boxes in background jobs and resume after unlock
  3. Check IsEncryptedBox/isBoxUnlockedForAccess before scheduling work on the box
Defensive patterns

Strategy: validation

Validate before calling

if model.IsEncryptedBox(boxID) && !model.IsBoxUnlockedForAccess(boxID) { return errors.New("unlock the encrypted notebook before this operation") }

Try / catch

dek, err := model.GetDEK(boxID); if err != nil && strings.Contains(err.Error(), "not accessible") { /* prompt the user to unlock, then retry */ }

Prevention

When it happens

Trigger: Calling GetDEK for a box where IsEncryptedBox(boxID) is true but the user has not unlocked it in this session (no UnlockEncryptedBox / notebook mounted locked), or after the box was re-locked or the DEK cache was cleared.

Common situations: A background job (asset indexing, db sync) running after the user locked the notebook; an operation triggered on a locked encrypted notebook via API; app restart that cleared in-memory DEKs.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/d03bb29d1e67c9f7. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/crypto.go:1678

}

// 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 9f775e8a12)