siyuan-note/siyuan · error

Invalid key backup file

Error message

Invalid key backup file

What it means

Error "Invalid key backup file" thrown in siyuan-note/siyuan.

Solutions

  1. Verify the backup file's Argon2 KDF parameters are within the supported ranges; a file with invalid parameters is rejected here.
  2. Do not hand-edit the notebook crypto backup file; restore an unmodified backup produced by SiYuan.
  3. If the backup is corrupt, restore the original conf.json or an earlier backup copy and retry.

When it happens

Trigger: Thrown at kernel/model/crypto.go:1177 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/925a3129b68aab07. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/crypto.go:1177

	// 调用方已持有 notebookCryptoMu,且 writeNotebookCryptoBackupData 不再申请该锁,故无死锁;
	// 同步写避免与 ChangeMasterPassword 的并发备份写竞争同一文件(lost update 导致 verifier 被回退)。
	nc := *backup
	if err := writeNotebookCryptoBackupData(&nc, kek); err != nil {
		logging.LogWarnf("rewrite notebook crypto backup after restore failed: %s", err)
	}
	logging.LogInfof("notebook crypto restored from backup (e.g. after sync to a new device)")
	return kek, nil
}

// deriveNotebookCryptoBackupCandidate 对同步备份做无副作用验证,并确认它覆盖全部现有加密笔记本。
func deriveNotebookCryptoBackupCandidate(password string) (backup *conf.NotebookCrypto, kek []byte, err error) {
	backup, err = loadNotebookCryptoBackup()
	if err != nil || backup == nil || len(backup.MasterSalt) == 0 || len(backup.KEKVerifier) == 0 {
		return nil, nil, errors.New(Conf.Language(310))
	}
	params, validErr := util.ValidateArgon2Params(backup.KDFParams)
	if validErr != nil {
		return nil, nil, errors.New(Conf.Language(317))
	}
	kek = util.DeriveKey(password, backup.MasterSalt, params)
	decrypted, decryptErr := util.DecryptWithAAD(kek, backup.KEKVerifier, []byte("siyuan:kek-verifier"))
	if decryptErr != nil || string(decrypted) != string(kekVerifierMagic) {
		zeroAndClear(kek)
		return nil, nil, errors.New(Conf.Language(311))
	}
	if backup.Spec != conf.CurrentNotebookCryptoSpec || backup.Checksum == "" ||
		len(backup.KEKMAC) == 0 || !verifyKEKMAC(backup, kek) {
		zeroAndClear(kek)
		return nil, nil, errors.New(Conf.Language(316))
	}
	if !verifyKEKAgainstExistingBoxes(kek) || !verifyKEKAgainstEncryptedHistory(kek) {
		zeroAndClear(kek)
		return nil, nil, errors.New(Conf.Language(316))
	}
	backup.KDFParams = params
	return backup, kek, nil

View on GitHub (pinned to afa823b6b4)