siyuan-note/siyuan · error
missing encrypted index setting %s
Error message
missing encrypted index setting %s
What it means
OpenEncryptedDB/OpenEncryptedBlockTreeDB run this check after opening a SQLCipher-encrypted SQLite index. It reads SQLCipher PRAGMAs (cipher_version, cipher_page_size, kdf_iter, cipher_hmac_algorithm, cipher_kdf_algorithm, cipher_use_hmac) and requires each to return a non-empty value so the settings can be fingerprinted into compatibility metadata. An empty value means the database was not opened with SQLCipher (plain SQLite) or the SQLCipher build reports no setting, so the compatibility fingerprint cannot be recorded.
Source
Thrown at kernel/util/encrypted_index.go:24
import (
"database/sql"
"encoding/json"
"errors"
"fmt"
)
// CheckEncryptedIndexCompatibility 将索引版本保存在受 SQLCipher 认证的表中,拒绝复用缺少版本或参数不匹配的旧索引。
// schema 由各索引维护,修改表结构时递增;索引重建由已认证源文档的调用方负责。
func CheckEncryptedIndexCompatibility(db *sql.DB, kind string, schema int) error {
settings := map[string]string{}
for _, name := range []string{"cipher_version", "cipher_page_size", "kdf_iter", "cipher_hmac_algorithm", "cipher_kdf_algorithm", "cipher_use_hmac"} {
var value string
if err := db.QueryRow("PRAGMA " + name).Scan(&value); err != nil {
return fmt.Errorf("read encrypted index setting %s: %w", name, err)
}
if value == "" {
return fmt.Errorf("missing encrypted index setting %s", name)
}
settings[name] = value
}
encoded, err := json.Marshal(settings)
if err != nil {
return err
}
var metadataTables int
if err = db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type = 'table' AND name = 'encrypted_index_meta'").Scan(&metadataTables); err != nil {
return err
}
if metadataTables == 0 {
var tables int
if err = db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type = 'table'").Scan(&tables); err != nil {
return err
}
if tables != 0 {
return errors.New("encrypted index has no compatibility metadata")View on GitHub (pinned to 8641553a1f)
Solutions
- Ensure the SQLite driver is the SQLCipher build (maintainer's fork with cipher support via kernel/go.mod replace) and rebuild the kernel binary
- Verify with the same connection that PRAGMA cipher_version returns non-empty; if empty the binary was linked against plain SQLite
- If the database is genuinely a legacy plaintext index, open it through the plain open path or migrate it to the encrypted format before calling OpenEncryptedDB
- Check go.mod for accidental replaces of go-sqlite3 with an upstream non-cipher version and remove them
Example fix
// before: driver compiled without SQLCipher, PRAGMA cipher_version = "" // after: use the cipher-enabled fork and build tags in kernel/go.mod require github.com/siyuan-note/go-sqlite3 ... // keep the permanent replace pointing at the cipher-enabled fork
Defensive patterns
Strategy: validation
Validate before calling
var v string
if err := db.QueryRow("PRAGMA cipher_version").Scan(&v); err != nil || v == "" {
return fmt.Errorf("driver is not SQLCipher-enabled")
} Try / catch
if err := CheckEncryptedIndexCompatibility(db, kind, schema); err != nil {
log.Printf("encrypted index unusable, rebuilding: %v", err)
return rebuildIndexFromSources()
} Prevention
- Always build the kernel with the cipher-enabled SQLite fork from kernel/go.mod
- Smoke-test PRAGMA cipher_version at startup before opening encrypted indexes
- Never add temporary replaces of go-sqlite3 that drop cipher support
When it happens
Trigger: CheckEncryptedIndexCompatibility is called on an *sql.DB whose underlying driver is plain SQLite instead of SQLCipher, so every 'PRAGMA cipher_*' query returns an empty string. Also triggered by a SQLCipher version that does not expose one of the six pragmas queried.
Common situations: Linking kernel against a stock mattn/go-sqlite3 build without the cipher tags; a dependency replace silently swapping the SQLCipher fork for vanilla SQLite; running on a platform where the cipher extension failed to compile in; opening a pre-encryption (legacy plaintext) siyuan.db through the encrypted-open path.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- read encrypted index setting %s: %w
- encrypted box db not opened for box
- query database-bound blocks in notebook [%s] failed: %w
- encrypted box db not opened for box %s
- encrypted box db not opened for box %s
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/eaf439255d3ac285.
Report an issue: GitHub.