{"record":{"id":"4a531c931940342f","repo":"siyuan-note/siyuan","slug":"311","errorCode":"311","errorMessage":"Incorrect master password","messagePattern":"Incorrect master password","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/crypto.go","lineNumber":1006,"sourceCode":"\n\thasEncrypted, listErr := hasEncryptedNotebook()\n\tif listErr != nil {\n\t\treturn fmt.Errorf(\"list encrypted notebooks failed: %w\", listErr)\n\t}\n\thasHistory, historyErr := scanEncryptedNotebookHistory()\n\tif historyErr != nil {\n\t\treturn fmt.Errorf(\"check encrypted notebook history failed: %w\", historyErr)\n\t}\n\thasBackup := filelock.IsExist(dataCryptoBackupPath())\n\tif hasEncrypted || hasHistory || hasBackup {\n\t\t// 现存笔记本、已删除笔记本历史或全局备份均表示已有密钥域，必须恢复并认证，不能生成新 MasterSalt。\n\t\tkek, restoreErr := tryRestoreNotebookCryptoFromBackupLocked(password)\n\t\tif kek != nil {\n\t\t\tzeroAndClear(kek)\n\t\t}\n\t\tif restoreErr != nil {\n\t\t\tif strings.Contains(restoreErr.Error(), Conf.Language(311)) {\n\t\t\t\treturn errors.New(Conf.Language(311))\n\t\t\t}\n\t\t\treturn errors.New(Conf.Language(315))\n\t\t}\n\t\tlogging.LogInfof(\"encrypted notebook re-enabled with authenticated recovery key material\")\n\t\treturn nil\n\t}\n\n\t// 不存在任何密钥依赖或备份时生成新的 MasterSalt。\n\tsalt, err := util.GenerateSalt()\n\tif err != nil {\n\t\treturn err\n\t}\n\tConf.m.RLock()\n\tkdfParams := Conf.NotebookCrypto.KDFParams\n\tConf.m.RUnlock()\n\tparams, validErr := util.ValidateArgon2Params(kdfParams)\n\tif validErr != nil {\n\t\treturn validErr","sourceCodeStart":988,"sourceCodeEnd":1024,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/crypto.go#L988-L1024","documentation":"EnableEncryptedNotebook returns Conf.Language(311) ('incorrect master password') at line 1006 when the device already has encrypted notebooks, history, or a backup (hasEncrypted || hasHistory || hasBackup), and the recovery attempt via tryRestoreNotebookCryptoFromBackupLocked fails with an error whose message contains the Language(311) string. The recovery path derives a KEK from the supplied password and verifies it against the backup's KEKVerifier; failure means the password does not match the existing key domain. This is the expected error when a user tries to (re-)enable encryption with the wrong master password on a device that already holds encrypted data.","triggerScenarios":"On a device with existing encrypted notebooks/history/backup, the user calls EnableEncryptedNotebook with a password that cannot authenticate the persisted backup's KEKVerifier. tryRestoreNotebookCryptoFromBackupLocked returns an error containing Language(311), which is re-surfaced here.","commonSituations":"User mistypes the master password when re-enabling after a reinstall or on a synced device; user enters a new password thinking enable creates a fresh domain, while existing notebooks require the original; password changed elsewhere and the local backup was not yet updated.","solutions":["Enter the master password that matches the existing encrypted notebooks/backup on this device.","If the password was changed on another device, sync first so the backup reflects the current password, then retry.","If the password is truly forgotten, existing encrypted notebooks and history are unrecoverable by design — do not force a new enable."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Distinguish wrong-password (311) from missing-backup (315) on enable.\nif err := model.EnableEncryptedNotebook(password); err != nil {\n    if strings.Contains(err.Error(), Conf.Language(311)) {\n        // prompt for the correct existing master password\n    } else if strings.Contains(err.Error(), Conf.Language(315)) {\n        // recovery-required: backup missing\n    }\n}","preventionTips":["On a device with existing encrypted notebooks/history/backup, enable requires the ORIGINAL master password, not a new one.","Sync before enabling on a new device so the backup reflects the current password.","Distinguish Language(311) (wrong password) from Language(315) (recovery required) in user messaging."],"tags":["crypto","encryption","password","recovery","authentication"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}