SonarSource/sonarqube · warning · IllegalStateException

Failed to redirect to

Error message

Failed to redirect to ${url}

What it means

IllegalStateException from GithubManifestCallbackFilter.redirect: sendRedirect(url) threw an IOException while redirecting the user's browser during the GitHub App manifest callback. Indicates the client connection broke or the response was already committed.

Solutions

  1. Retry the GitHub App configuration flow
  2. Verify the callback URL is reachable and proxy timeouts are adequate
  3. Check server logs for the underlying IOException and response-commit state

Example fix

// before
redirect(response, url); // IOException -> IllegalStateException
// after
try {
  redirect(response, url);
} catch (IllegalStateException e) {
  logger.warn("Failed to redirect GitHub manifest callback", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
  filterChain.doFilter(request, response);
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Failed to redirect to ")) {
    logger.warn("GitHub manifest callback redirect failed (client gone or response committed)", e);
  } else { throw e; }
}

Prevention

When it happens

Trigger: doFilter processing the manifest callback calls redirect(response, url) and the servlet container throws IOException on sendRedirect — client gone, connection reset, or response already committed.

Common situations: User navigated away mid-callback; short proxy timeouts; double-invocation of the callback filter.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/86f6790492cbd87f. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubManifestCallbackFilter.java:250

  private String errorOn(String path, String message) {
    return manifestGenerator.baseUrl() + path + "&almManifestResult=error&almError=" + encode(message);
  }

  // Auth-only flows have no DevOps setting key and belong on the GitHub authentication settings page.
  private static String settingsPathFor(PendingManifest pending) {
    return pending.setupDevops() ? SETTINGS_PATH : AUTH_SETTINGS_PATH;
  }

  private static String encode(String value) {
    return URLEncoder.encode(value, StandardCharsets.UTF_8);
  }

  private static void redirect(HttpResponse response, String url) {
    try {
      response.sendRedirect(url);
    } catch (IOException e) {
      throw new IllegalStateException("Failed to redirect to " + url, e);
    }
  }

  @Override
  public void init() {
    // nothing to do
  }

  @Override
  public void destroy() {
    // nothing to do
  }
}

View on GitHub (pinned to 184c821202)