{"record":{"id":"7f28409007fb605e","repo":"theonedev/onedev","slug":"password-reset-url-is-invalid-or-obsolete","errorCode":null,"errorMessage":"Password reset url is invalid or obsolete","messagePattern":"Password reset url is invalid or obsolete","errorType":"exception","errorClass":"ExplicitException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/web/page/security/PasswordResetPage.java","lineNumber":181,"sourceCode":"\t\t\t\t\t\tuser.setPasswordResetCode(null);\n\t\t\t\t\t\tuser.setPassword(OneDev.getInstance(PasswordService.class).encryptPassword(bean.getNewPassword()));\n\t\t\t\t\t\tgetUserService().update(user, null);\n\t\t\t\t\t\tSession.get().success(_T(\"Password changed. Please login with your new password\"));\n\t\t\t\t\t\tsetResponsePage(LoginPage.class);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tform.add(BeanContext.edit(\"editor\", bean));\n\t\t\t\tform.add(new Link<Void>(\"cancel\") {\n\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic void onClick() {\n\t\t\t\t\t\tsetResponsePage(LoginPage.class);\n\t\t\t\t\t}\n\n\t\t\t\t});\n\t\t\t\tfragment.add(form);\n\t\t\t} else {\n\t\t\t\tthrow new ExplicitException(_T(\"Password reset url is invalid or obsolete\"));\n\t\t\t}\n\t\t}  \n\t}\n\t\n\tprivate UserService getUserService() {\n\t\treturn OneDev.getInstance(UserService.class);\n\t}\n\t\n\t@Override\n\tprotected String getTitle() {\n\t\tif (passwordResetCode == null)\n\t\t\treturn _T(\"Forgotten Password?\");\n\t\telse \n\t\t\treturn _T(\"Enter New Password\");\n\t}\n\n\t@Override\n\tprotected String getSubTitle() {","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/web/page/security/PasswordResetPage.java#L163-L199","documentation":"PasswordResetPage.onInitialize validates the password-reset request token loaded from the URL. If the token is absent, expired, or already used, the page throws ExplicitException('Password reset url is invalid or obsolete') instead of showing the reset form, because reset links are single-use and time-limited.","triggerScenarios":"Opening a reset link whose token no longer resolves to a valid pending password-reset request — link already used once, link expired, password-reset record cleared, or the token parameter was truncated when copying the URL.","commonSituations":"Clicking a reset email link a second time; requesting a new reset (invalidating the old link) then using the older email; corporate mail scanner pre-fetching links; copy/paste losing part of the token.","solutions":["Request a new password reset email and use the newest link immediately, once.","Paste the full URL, ensuring the entire token parameter is intact.","If resets repeatedly fail, ask an admin to reset your password directly in user management.","Check server time/NTP if links seem to expire instantly."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if (passwordResetRequest == null) { /* treat link as obsolete, offer new reset */ }","typeGuard":null,"tryCatchPattern":"try {\n  openResetPage(token);\n} catch (ExplicitException e) {\n  // show 'request new reset link' form\n}","preventionTips":["Use the newest reset link only once and promptly.","Request a fresh link whenever unsure which email is current.","Beware mail-scanner link prefetching; prefer copy/paste.","Admins can reset passwords directly when links keep failing."],"tags":["password-reset","token-expired","authentication"],"backgroundTag":"token-expired","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}