{"record":{"id":"ac21cfc1f65a5905","repo":"theonedev/onedev","slug":"invalid-state-please-make-sure-you-are-visiting-o","errorCode":null,"errorMessage":"Invalid state. Please make sure you are visiting OneDev using server url specified in system setting","messagePattern":"Invalid state\\. Please make sure you are visiting OneDev using server url specified in system setting","errorType":"exception","errorClass":"ExplicitException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/web/page/security/OAuthCallbackPage.java","lineNumber":32,"sourceCode":"public class OAuthCallbackPage extends SimplePage {\n\n\tpublic static final String MOUNT_PATH = \"~oauth/callback\";\n\t\n\tprivate static final String PARAM_CODE = \"code\";\n\t\n\tprivate static final String PARAM_STATE = \"state\";\n\n\tprivate String code;\n\t\n\tprivate String state;\n\t\n\tpublic OAuthCallbackPage(PageParameters params) {\n\t\tsuper(params);\n\t\tstate = params.get(PARAM_STATE).toString();\n\t\tcode = params.get(PARAM_CODE).toString();\n\t\t\n\t\tif (!state.equals(Session.get().getAttribute(\"oauthState\"))) {\n\t\t\tthrow new ExplicitException(_T(\"Invalid state. Please make sure you are visiting \"\n\t\t\t\t\t+ \"OneDev using server url specified in system setting\"));\n\t\t} else {\n\t\t\tSession.get().setAttribute(\"oauthCode\", code);\n\t\t}\n\t}\n\n\t@Override\n\tprotected String getTitle() {\n\t\treturn _T(\"Please wait...\");\n\t}\n\n\t@Override\n\tprotected String getSubTitle() {\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic void renderHead(IHeaderResponse response) {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/web/page/security/OAuthCallbackPage.java#L14-L50","documentation":"OAuthCallbackPage validates the OAuth 'state' parameter against the 'oauthState' attribute stored in the Wicket session when the flow started. On mismatch it throws ExplicitException('Invalid state...') because the callback may be forged, replayed, or issued via a different server URL (session cookie not shared).","triggerScenarios":"The state query parameter in the OAuth provider's redirect does not equal the session's oauthState — the auth flow was started on a different host/URL than the callback URL configured in the OAuth provider, the session expired mid-flow, or the callback was opened in a different browser/session.","commonSituations":"Server url in system setting differs from the redirect URL registered with the SSO provider (http vs https, localhost vs domain), causing cookies/session mismatch; reverse proxy stripping cookies; user waiting too long between starting login and being redirected; double-opening the login flow.","solutions":["Set the server url in Admin > System Setting to the exact base URL users use, and make the OAuth provider's redirect/callback URL match it (same scheme and host).","Clear cookies / restart the browser session and retry the SSO login from scratch.","Check any reverse proxy forwards cookies and does not rewrite the Host header.","Ensure only one login flow is active; do not reuse an old callback URL directly."],"exampleFix":"// before (provider app config)\nredirect uri: http://localhost:6610/oauth2/callback\n// after (match the server url users actually visit)\nredirect uri: https://onedev.example.com/oauth2/callback","handlingStrategy":"retry","validationCode":"String expected = (String) Session.get().getAttribute(\"oauthState\");\nboolean valid = expected != null && expected.equals(stateParam);","typeGuard":null,"tryCatchPattern":"try {\n  new OAuthCallbackPage(params);\n} catch (ExplicitException e) {\n  // restart SSO login from the login page\n  setResponsePage(SignInPage.class);\n}","preventionTips":["Align server url and OAuth provider redirect URL exactly (scheme+host).","Start and finish the OAuth flow in the same browser session.","Avoid keeping login tabs open for long periods.","Ensure proxies preserve cookies and the Host header."],"tags":["oauth","sso","csrf-state"],"backgroundTag":"oauth-state-mismatch","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"}