{"record":{"id":"6d9472174b3ca0e0","repo":"semaphoreui/semaphore","slug":"error-generating-key","errorCode":null,"errorMessage":"Error generating key","messagePattern":"Error generating key","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"api/users.go","lineNumber":421,"sourceCode":"\n\tif !util.Config.Mfa.Totp.Enabled {\n\t\thelpers.WriteErrorStatus(w, \"TOTP not enabled\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tif user.Totp != nil {\n\t\thelpers.WriteErrorStatus(w, \"TOTP already enabled\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tkey, err := totp.Generate(totp.GenerateOpts{\n\t\tIssuer:      \"Semaphore\",\n\t\tAccountName: user.Email,\n\t})\n\n\tif err != nil {\n\t\tc.log.WithError(err).WithFields(log.Fields{\"user_id\": user.ID}).Error(\"Failed to generate TOTP key\")\n\t\thttp.Error(w, \"Error generating key\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tvar code, hash string\n\n\tif util.Config.Mfa.Totp.AllowRecovery {\n\t\tcode, hash, err = util.GenerateRecoveryCode()\n\t\tif err != nil {\n\t\t\thelpers.WriteError(w, err)\n\t\t\treturn\n\t\t}\n\t}\n\n\tnewTotp, err := helpers.Store(r).AddTotpVerification(user.ID, key.URL(), hash)\n\tif err != nil {\n\t\thelpers.WriteError(w, err)\n\t\treturn\n\t}","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/api/users.go#L403-L439","documentation":"Returned by the EnableTotp HTTP handler when the TOTP key generation library call (e.g. pquerna/otp) fails for the authenticated user. The server logs the underlying cause with the user_id and responds with HTTP 500 'Error generating key'. It means a TOTP secret could not be created for multi-factor enrollment, usually due to an invalid email/issuer combination or an internal crypto failure.","triggerScenarios":"POST to the user's TOTP enable endpoint when otp.Generate fails — e.g. the user.Email is empty/invalid as an account name, a nil/invalid random source, or an error returned by the TOTP generation options (Issuer 'Semaphore', AccountName user.Email).","commonSituations":"Database returned a user record with a malformed or empty email; a corrupted/random-source issue on the server; MFA enrollment attempted against an older user row lacking an email after a migration or LDAP sync.","solutions":["Check the server log line 'Failed to generate TOTP key' for the underlying error and user_id","Verify the user's email field is non-empty and valid in the users table","Re-run TOTP enablement after fixing the user record; if generation is flaky, retry the request","Check the OTP library version for known issues with key generation options"],"exampleFix":"// before\nIssuer:      \"Semaphore\",\nAccountName: user.Email,\n// after\naccountName := user.Email\nif accountName == \"\" {\n    accountName = user.Username // or fail early with a 400\n}\nIssuer:      \"Semaphore\",\nAccountName: accountName,","handlingStrategy":"validation","validationCode":"if user == nil || strings.TrimSpace(user.Email) == \"\" {\n    return errors.New(\"user has no valid email for TOTP account name\")\n}\n// then call the TOTP enable endpoint","typeGuard":"func hasValidEmail(u *db.User) bool { return u != nil && strings.TrimSpace(u.Email) != \"\" }","tryCatchPattern":null,"preventionTips":["Ensure every user row has a non-empty email before enabling MFA","Check server logs (user_id) for the underlying OTP library error on 500 responses","Keep the OTP library up to date","Add a pre-flight admin check that user records are complete after imports/syncs"],"tags":["totp","mfa","http-500","internal-server-error"],"backgroundTag":"http-error-response","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}