siyuan-note/siyuan · error

Master password change partially failed. Please restart SiYu

Error message

Master password change partially failed. Please restart SiYuan to complete recovery. Detail: %s

What it means

Thrown in ChangeMasterPassword Phase 3 when a notebook's conf is missing/damaged and the attempt to rebuild it from the per-notebook backup fails at box.SaveConf. This wraps errMasterPasswordMigrationPending (a sentinel) with Language(320), producing the user-facing 'Master password change partially failed. Please restart SiYuan to complete recovery.' The migration manifest has already been written (Phase 1) and the global verifier switched (Phase 2), so the state is recoverable.

Source

Thrown at kernel/model/crypto.go:1780

	Conf.NotebookCrypto.KDFParams = params
	Conf.m.Unlock()

	// Conf.Save 内部会加 Conf.m,不能在持锁状态下调用(RWMutex 不可重入)
	Conf.Save()

	// Phase 3: 写入各 box conf + backup
	for _, entry := range entries {
		box := &Box{ID: entry.BoxID}
		boxConf := box.GetConf()
		if !boxConf.Encrypted || boxConf.BoxCrypt == nil {
			// conf 缺失/损坏:尝试从 per-notebook backup 重建
			backup, bErr := readNotebookCryptBackup(entry.BoxID)
			if bErr == nil && backup != nil && len(backup.WrappedDEK) > 0 {
				boxConf = box.GetConf()
				boxConf.Encrypted = true
				boxConf.BoxCrypt = backup
				if saveErr := box.SaveConf(boxConf); saveErr != nil {
					return fmt.Errorf("%w: %s", errMasterPasswordMigrationPending,
						fmt.Sprintf(Conf.Language(320), entry.BoxID+": rebuild encrypted conf from backup failed: "+saveErr.Error()))
				}
			} else {
				// conf 与 backup 均不可用:manifest 是该 box 加密密钥的权威来源,直接从 entry 重建 BoxCrypt,
				// 避免改密因瞬时 conf 损坏而中断(详见 recoverMasterPasswordMigration 中的对称处理)。
				logging.LogWarnf("rebuild encrypted box [%s] from migration entry (conf and backup both unavailable)", entry.BoxID)
				boxConf = box.GetConf()
				boxConf.Encrypted = true
				boxConf.BoxCrypt = &conf.BoxEncryption{
					WrappedDEK: entry.NewWrappedDEK,
					WrapNonce:  entry.NewWrapNonce,
					Spec:       entry.NewSpec,
					Metadata:   entry.Metadata,
					CreatedAt:  time.Now().UnixMilli(),
				}
				if saveErr := box.SaveConf(boxConf); saveErr != nil {
					return fmt.Errorf("%w: %s", errMasterPasswordMigrationPending,
						fmt.Sprintf(Conf.Language(320), entry.BoxID+": rebuild encrypted conf from migration entry failed: "+saveErr.Error()))

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Restart SiYuan — recoverMasterPasswordMigration runs during Boot and will complete the pending conf writes using the migration manifest.
  2. Check the detail string in the error message for the specific SaveConf failure (e.g., 'permission denied', 'no space left on device').
  3. Free disk space or fix permissions, then restart so recovery can succeed.
  4. Do not manually edit conf.json or the manifest while a migration is pending — let the recovery logic handle it.
Defensive patterns

Strategy: retry

Try / catch

// These errors (633-637) all wrap errMasterPasswordMigrationPending.
// The correct handling is to detect the sentinel and inform the user
// to restart SiYuan for recovery:
if errors.Is(err, model.ErrMasterPasswordMigrationPending) {
    // inform user: restart SiYuan to complete recovery
    // recovery runs automatically during Boot
}

Prevention

When it happens

Trigger: During Phase 3 of ChangeMasterPassword, for a notebook whose boxConf.Encrypted is false or boxConf.BoxCrypt is nil: readNotebookCryptBackup succeeds (backup has WrappedDEK), but box.SaveConf fails (filesystem write error). The migration is left partially applied — global verifier is new, but this notebook's conf hasn't been updated.

Common situations: Disk full or filesystem write error during password change. Permissions changed between read and write. File locking conflict with another process. The manifest on disk ensures that on next restart, recoverMasterPasswordMigration will detect the pending state and retry the conf writes.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/3d3f2ef3ad601f5b. Report an issue: GitHub.