theonedev/onedev · error · AuthenticationException
Invalid state response
Error message
Invalid state response
What it means
Thrown by DiscordConnector.handleAuthResponse when Discord redirects back to the SSO callback without a 'code' parameter but also without a recognizable error, meaning the OAuth2 'state' check cannot be completed. The connector treats any callback whose state does not match what it originally sent as an unsolicited or forged response and rejects authentication.
Source
Thrown at server-plugin/server-plugin-sso-discord/src/main/java/io/onedev/server/plugin/sso/discord/DiscordConnector.java:92
DiscordAuthorizationCodeResponse codeResponse = new DiscordAuthorizationCodeResponse(request.getQueryString());
if (codeResponse.hasValidCode()) {
Request apiRequest = getCachedApiRequest();
if (codeResponse.hasState(apiRequest.getState())) {
try {
AccessTokenResponse accessTokenResponse = apiRequest.getToken(getClientSecret(), codeResponse.getCode());
if (accessTokenResponse.isOK() && accessTokenResponse.hasValidAccessToken()) {
return processTokenResponse(accessTokenResponse);
}
throw new AuthenticationException(accessTokenResponse.getContent());
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
throw new AuthenticationException(_T("Invalid state response"));
}
} else {
throw new AuthenticationException(codeResponse.getError());
}
}
@Override
public String buildAuthUrl(String providerName) {
Request apiRequest = new Request(getClientId(), getScopes(), getCallbackUri(providerName).toString());
Session.get().setAttribute(SESSION_ATTR_API_REQUEST, apiRequest);
String authURI = apiRequest.getAuthorizationURI();
return authURI;
}
private SsoAuthenticated processTokenResponse(AccessTokenResponse accessTokenResponse) {
try {
final boolean bCheckGuilds = !StringUtils.isEmpty(getServerId());View on GitHub (pinned to d44925c47c)
Solutions
- Restart the SSO login flow from the beginning (click the Discord sign-in button again) instead of reusing/reloading the callback URL.
- Ensure browser cookies for the OneDev server are enabled so the Wicket session (holding the state) survives the redirect.
- Verify no proxy/CDN is stripping query parameters (state/code) from the callback URL.
- Avoid running multiple concurrent SSO logins in the same browser session.
Defensive patterns
Strategy: try-catch
Try / catch
try {
connector.handleAuthResponse(...);
} catch (AuthenticationException e) {
if (e.getMessage().contains("Invalid state response")) {
// restart SSO flow: redirect user to sign-in again
}
} Prevention
- Enable session cookies in browsers used for SSO.
- Don't reload or bookmark OAuth callback URLs.
- Avoid parallel SSO logins in one browser session.
- Check proxies preserve query parameters.
When it happens
Trigger: Discord's authorization endpoint returns to the callback URL and the connector's expected session state is absent/mismatched while parsing the code response; typically a callback arriving outside the original login flow (e.g. after session loss or replaying an old callback URL).
Common situations: User opens the callback URL directly or refreshes it after the Wicket session expired; reverse proxy strips query parameters; user has two SSO tabs open and states overwrite each other; browser blocked session cookies.
Related errors
- Unsolicited discord api response
- You are not member of discord server
- Unable to get guilds info
- Unsolicited OIDC authentication response
- Invalid state. Please make sure you are visiting OneDev usin
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/e81f7155abddab11.
Report an issue: GitHub.