siyuan-note/siyuan · error

invalid encrypted index compatibility metadata

Error message

invalid encrypted index compatibility metadata

What it means

The encrypted_index_meta table exists but does not contain exactly one row. The compatibility contract requires a single metadata row holding kind, schema_version, and the cipher-settings fingerprint. Zero rows (table created but insert never ran, e.g. an interrupted initialization) or multiple rows mean the metadata is corrupt, so the library cannot authenticate which format the index was built with.

Source

Thrown at kernel/util/encrypted_index.go:56

		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")
		}
		if _, err = db.Exec("CREATE TABLE encrypted_index_meta (kind TEXT NOT NULL, schema_version INTEGER NOT NULL, cipher_settings TEXT NOT NULL)"); err != nil {
			return err
		}
		_, err = db.Exec("INSERT INTO encrypted_index_meta VALUES (?, ?, ?)", kind, schema, string(encoded))
		return err
	}
	var storedKind, storedSettings string
	var storedSchema, rows int
	if err = db.QueryRow("SELECT count(*) FROM encrypted_index_meta").Scan(&rows); err != nil {
		return err
	}
	if rows != 1 {
		return errors.New("invalid encrypted index compatibility metadata")
	}
	if err = db.QueryRow("SELECT kind, schema_version, cipher_settings FROM encrypted_index_meta").Scan(&storedKind, &storedSchema, &storedSettings); err != nil {
		return err
	}
	if storedKind != kind || storedSchema != schema || storedSettings != string(encoded) {
		return errors.New("incompatible encrypted index")
	}
	return nil
}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Treat the index as unrecoverable metadata: delete the index file and let the kernel rebuild it from source documents (source ciphertext is not touched)
  2. If multiple rows exist, inspect with 'SELECT * FROM encrypted_index_meta' to see if a concurrent writer duplicated the row, then remove the offending writer
  3. Ensure only one SiYuan kernel instance runs against a workspace at a time before rebuilding

Example fix

-- inspect the corrupt metadata
SELECT count(*) FROM encrypted_index_meta; -- expect exactly 1
-- if not, rebuild the index from source documents
Defensive patterns

Strategy: validation

Validate before calling

var rows int
if err := db.QueryRow("SELECT count(*) FROM encrypted_index_meta").Scan(&rows); err != nil || rows != 1 {
    return fmt.Errorf("metadata invalid (rows=%d), index must be rebuilt", rows)
}

Try / catch

if err := CheckEncryptedIndexCompatibility(db, kind, schema); err != nil {
    if strings.Contains(err.Error(), "invalid encrypted index compatibility metadata") {
        return rebuildDerivedIndex()
    }
    return err
}

Prevention

When it happens

Trigger: OpenEncryptedDB/OpenEncryptedBlockTreeDB on a database where encrypted_index_meta has 0 or >= 2 rows — e.g. a partially created index where the CREATE TABLE succeeded but the INSERT failed or ran twice, or manual edits to the database.

Common situations: Kernel crash or power loss between table creation and metadata insertion; concurrent kernel instances writing the same workspace index; a user or tooling manipulating the SQLite file directly.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/feb9b24224672b72. Report an issue: GitHub.