siyuan-note/siyuan · error

encrypted index has no compatibility metadata

Error message

encrypted index has no compatibility metadata

What it means

After the cipher settings fingerprint is built, CheckEncryptedIndexCompatibility looks for the encrypted_index_meta table that stores kind, schema_version, and cipher_settings. If the table is absent but the database is NOT empty (tables > 0), the index was created by a build that predates compatibility metadata, and the library refuses to touch it rather than guess its format. If the database is empty, the metadata table is created and a row is inserted instead.

Source

Thrown at kernel/util/encrypted_index.go:42

			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")
		}
		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
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Delete the stale generated index (siyuan.db / blocktree.db) and let the kernel rebuild it from the .sy source documents — derived indexes are safe to rebuild
  2. If rebuilding is not possible, open the index with the kernel version that created it, export data, then re-import into the new version
  3. Check docs/ENCRYPTED-NOTEBOOK.md for the supported migration path for old encrypted indexes before deleting anything
Defensive patterns

Strategy: fallback

Validate before calling

var n int
_ = db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='encrypted_index_meta'").Scan(&n)
legacy := n == 0

Try / catch

if err := CheckEncryptedIndexCompatibility(db, kind, schema); err != nil {
    if strings.Contains(err.Error(), "no compatibility metadata") {
        return rebuildDerivedIndex() // sources are untouched
    }
    return err
}

Prevention

When it happens

Trigger: Calling OpenEncryptedDB or OpenEncryptedBlockTreeDB on an existing encrypted index whose file contains other tables but no encrypted_index_meta table — i.e. an index created before the encrypted-notebook compatibility-metadata schema was introduced.

Common situations: Upgrading SiYuan from a pre-metadata encrypted-index build over an existing workspace; restoring an old history.db/blocktree.db backup; pointing a new kernel version at a workspace whose index files were generated by an older release.

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/2aa374f20bf3e494. Report an issue: GitHub.