siyuan-note/siyuan · error

Decryption failed: incorrect key or corrupted data

Error message

Decryption failed: incorrect key or corrupted data

What it means

Error "Decryption failed: incorrect key or corrupted data" thrown in siyuan-note/siyuan.

Solutions

  1. Re-enter the master password; the KEK verifier decryption failed, which usually means the password is incorrect.
  2. If the password is correct, the backup data is corrupted or was replaced; restore the original backup file and retry.
  3. Check that the backup was not truncated by an interrupted sync; re-sync or restore from a known-good device.

When it happens

Trigger: Thrown at kernel/model/crypto.go:1188 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/9ffd4e881c045d8f. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/crypto.go:1188

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
}

// deriveKEK 从主密码派生 KEK 并校验。校验失败返回错误。KEK 仅在函数作用域内有效,调用方负责使用。
func deriveKEK(password string) ([]byte, error) {
	Conf.m.RLock()
	nc := *Conf.NotebookCrypto
	Conf.m.RUnlock()

	if !nc.Enabled {
		// 本机未启用:可能是数据同步到新设备后本机 conf.json 还没有加密配置。
		// 尝试从 DataDir 备份恢复(备份会随 DataDir 同步过来);恢复成功时直接复用其派生的 KEK。

View on GitHub (pinned to afa823b6b4)