{"record":{"id":"168900d4aac20eb8","repo":"RocketChat/Rocket.Chat","slug":"failed-to-encode-private-key-with-provided-passwor","errorCode":null,"errorMessage":"Failed to encode private key with provided password.","messagePattern":"Failed to encode private key with provided password\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"apps/meteor/client/lib/e2ee/rocketchat.e2e.ts","lineNumber":291,"sourceCode":"\t}\n\n\tremoveInstanceByRoomId(rid: IRoom['_id']): void {\n\t\tdelete this.instancesByRoomId[rid];\n\t}\n\n\tprivate async persistKeys(\n\t\t{ public_key, private_key }: KeyPair,\n\t\tpassword: string,\n\t\t{ force }: { force: boolean } = { force: false },\n\t): Promise<void> {\n\t\tif (typeof public_key !== 'string' || typeof private_key !== 'string') {\n\t\t\tthrow new Error('Failed to persist keys as they are not strings.');\n\t\t}\n\n\t\tconst encodedPrivateKey = await this.keychain.encryptKey(private_key, password);\n\n\t\tif (!encodedPrivateKey) {\n\t\t\tthrow new Error('Failed to encode private key with provided password.');\n\t\t}\n\n\t\tawait sdk.rest.post('/v1/e2e.setUserPublicAndPrivateKeys', {\n\t\t\tpublic_key,\n\t\t\tprivate_key: JSON.stringify(encodedPrivateKey),\n\t\t\tforce,\n\t\t});\n\t}\n\n\tasync acceptSuggestedKey(rid: string): Promise<void> {\n\t\tawait sdk.rest.post('/v1/e2e.acceptSuggestedGroupKey', {\n\t\t\trid,\n\t\t});\n\t}\n\n\tasync rejectSuggestedKey(rid: string): Promise<void> {\n\t\tawait sdk.rest.post('/v1/e2e.rejectSuggestedGroupKey', {\n\t\t\trid,","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/client/lib/e2ee/rocketchat.e2e.ts#L273-L309","documentation":"persistKeys throws this when keychain.encryptKey(private_key, password) returns a falsy value, meaning the password-based encryption of the private key failed before anything is sent to /v1/e2e.setUserPublicAndPrivateKeys. The guard exists because a falsy encoded key would otherwise persist unusable key material server-side.","triggerScenarios":"Calling persistKeys with an empty or malformed password, when password-based key derivation inside the keychain fails (transient WebCrypto issue, non-secure context), or when a custom keychain implementation returns undefined on error instead of throwing.","commonSituations":"E2EE setup where the supplied password does not match expectations (account password flow), corrupted keychain state after a browser storage issue, private/incognito modes restricting crypto or storage APIs.","solutions":["Verify the password argument is non-empty and is the password the keychain expects (account password in the default flow).","Retry the operation once — transient crypto/derivation failures can yield a falsy result.","If it persists, reset E2EE state, regenerate the key pair, and persist with { force: true }."],"exampleFix":"// before\nawait e2e.persistKeys(keyPair, password);\n\n// after\nfor (let attempt = 0; attempt < 2; attempt++) {\n  try {\n    await e2e.persistKeys(keyPair, password, { force: attempt > 0 });\n    break;\n  } catch (e) {\n    if (attempt === 1) throw e;\n    password = await promptPasswordAgain();\n  }\n}","handlingStrategy":"retry","validationCode":"if (!password) {\n  throw new Error('E2EE password required');\n}\nawait e2e.persistKeys(keyPair, password);","typeGuard":null,"tryCatchPattern":"let lastErr: unknown;\nfor (let attempt = 0; attempt < 2; attempt++) {\n  try {\n    await e2e.persistKeys(keyPair, password, { force: attempt > 0 });\n    lastErr = undefined;\n    break;\n  } catch (e) {\n    lastErr = e;\n    password = await promptPasswordAgain(); // fresh, verified password\n  }\n}\nif (lastErr) throw lastErr;","preventionTips":["Validate the password is non-empty and matches the account flow before persisting keys.","Never ignore a falsy encryptKey result — abort and re-derive instead of persisting.","If retries keep failing, reset E2EE state and regenerate keys with force: true."],"tags":["e2ee","encryption","password"],"backgroundTag":"e2ee-key-encryption-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}