SonarSource/sonarqube · error · IllegalStateException

Failed to get

Error message

Failed to get %s

What it means

Thrown by OAuthRestClient.readPage when an IOException occurs while fetching a page of a paginated REST endpoint (used e.g. by Bitbucket/GitHub organization or workspace lookups). The failing endPoint URL is embedded in the message and the IOException is chained as the cause.

Solutions

  1. Inspect the chained cause (IOException) and endPoint in the message to identify the unreachable URL and network failure mode.
  2. Verify network/proxy connectivity from the SonarQube server to the identity provider API host.
  3. Confirm apiURL points to a reachable, correct base URL.
  4. Retry after transient network issues; check API rate limits if failures are persistent.

Example fix

// before
readNextEndPoint(nextResponse).ifPresent(newNextEndPoint -> readPage(result, scribe, accessToken, newNextEndPoint, function));
// after (guard with retry for transient failures)
readNextEndPoint(nextResponse).ifPresent(newNextEndPoint -> {
  try {
    readPage(result, scribe, accessToken, newNextEndPoint, function);
  } catch (IllegalStateException e) {
    LOG.warn("Retrying page fetch for {}", newNextEndPoint, e);
    readPage(result, scribe, accessToken, newNextEndPoint, function);
  }
});
Defensive patterns

Strategy: retry

Validate before calling

// Reachability pre-check before paginated calls
try (Socket s = new Socket()) {
    s.connect(new InetSocketAddress(host, 443), 3000); // fails fast if unreachable
}

Try / catch

try {
    executePaginatedRequest(...);
} catch (IllegalStateException e) {
    if (e.getCause() instanceof IOException io) {
        LOG.warn("Paginated fetch failed for {}, retrying once", e.getMessage(), io);
    }
}

Prevention

When it happens

Trigger: executePaginatedRequest follows Link headers page by page; any page fetch that throws IOException (connection reset, timeout, DNS failure, TLS error, stream read failure) is wrapped in this IllegalStateException.

Common situations: Network instability between SonarQube and the identity provider API; proxy/firewall blocking subsequent page requests; rate limiting closing connections; incorrect apiURL host unreachable.

Related errors


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

Appendix: source

Thrown at server/sonar-auth-common/src/main/java/org/sonar/auth/OAuthRestClient.java:85

    readPage(result, scribe, accessToken, addPerPageQueryParameter(request, DEFAULT_PAGE_SIZE), function);
    return result;
  }

  public static String addPerPageQueryParameter(String request, int pageSize) {
    String separator = request.contains("?") ? "&" : "?";
    return request + separator + "per_page=" + pageSize;
  }

  private static <E> void readPage(List<E> result, OAuth20Service scribe, OAuth2AccessToken accessToken, String endPoint, Function<String, List<E>> function) {
    try (Response nextResponse = executeRequest(endPoint, scribe, accessToken)) {
      String content = nextResponse.getBody();
      if (content == null) {
        return;
      }
      result.addAll(function.apply(content));
      readNextEndPoint(nextResponse).ifPresent(newNextEndPoint -> readPage(result, scribe, accessToken, newNextEndPoint, function));
    } catch (IOException e) {
      throw new IllegalStateException(format("Failed to get %s", endPoint), e);
    }
  }

  private static Optional<String> readNextEndPoint(Response response) {
    String link = response.getHeaders().entrySet().stream()
      .filter(e -> "Link".equalsIgnoreCase(e.getKey()))
      .map(Map.Entry::getValue)
      .findAny().orElse("");

    Matcher nextLinkMatcher = NEXT_LINK_PATTERN.matcher(link);
    if (!nextLinkMatcher.find()) {
      return Optional.empty();
    }
    return Optional.of(nextLinkMatcher.group(1));
  }

  private static IllegalStateException unexpectedResponseCode(String requestUrl, Response response) throws IOException {
    return new IllegalStateException(format("Fail to execute request '%s'. HTTP code: %s, response: %s", requestUrl, response.getCode(), response.getBody()));

View on GitHub (pinned to 184c821202)