SonarSource/sonarqube · error · IllegalStateException

Failed to create GitHub's user access token. GitHub returned

Error message

Failed to create GitHub's user access token. GitHub returned code 

What it means

createUserAccessToken exchanges an OAuth code for a user access token via GitHub's login/oauth/access_token endpoint. If GitHub returns a non-200 code, the response body is logged at DEBUG and this IllegalStateException is thrown including the returned code. It indicates the token exchange HTTP call itself failed rather than an application-level rejection.

Source

Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java:385

      throw new IllegalStateException(format("Failed to get repository '%s' on '%s' (this might be related to the GitHub App installation scope)",
        organizationAndRepository, appUrl), e);
    }
  }

  @Override
  public UserAccessToken createUserAccessToken(String appUrl, String clientId, String clientSecret, String code) {
    try {
      String endpoint = "/login/oauth/access_token?client_id=" + clientId + "&client_secret=" + clientSecret + "&code=" + code;

      String baseAppUrl = convertApiUrlToBaseUrl(appUrl);

      ApplicationHttpClient.Response response = githubApplicationHttpClient.post(baseAppUrl, null, endpoint);

      if (response.getCode() != HTTP_OK) {
        if (LOG.isDebugEnabled()) {
          LOG.debug("Failed to create GitHub's user access token, response body: {}", response.getContent().orElse(""));
        }
        throw new IllegalStateException("Failed to create GitHub's user access token. GitHub returned code " + response.getCode() + ".");
      }

      Optional<String> content = response.getContent();
      Optional<UserAccessToken> accessToken = content.flatMap(c -> Arrays.stream(c.split("&"))
          .filter(t -> t.startsWith("access_token="))
          .map(t -> t.split("=")[1])
          .findAny())
        .map(UserAccessToken::new);

      if (accessToken.isPresent()) {
        return accessToken.get();
      }

      // If token is not in the 200's body, it's because the client ID or client secret are incorrect
      LOG.error("Failed to create GitHub's user access token. GitHub's response: {}", content);
      throw new IllegalArgumentException();
    } catch (IOException e) {
      throw new IllegalStateException("Failed to create GitHub's user access token", e);

View on GitHub (pinned to 184c821202)

Solutions

  1. Enable DEBUG logging for org.sonar.alm.client to see the response body details.
  2. Verify the appUrl points to the correct GitHub instance root (api base used to build the endpoint).
  3. Confirm network connectivity from the SonarQube server to the GitHub host.
  4. Retry the authorization flow to obtain a fresh code; if the code was the issue, error 45/400-family messaging typically applies instead.

Example fix

// before
client.createUserAccessToken("https://ghe.example.com/bad", clientId, secret, code);
// after
client.createUserAccessToken("https://ghe.example.com", clientId, secret, code);
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight
if (!appUrl.startsWith("https://")) throw new IllegalArgumentException("appUrl must be https");
if (clientId == null || clientId.isBlank() || clientSecret == null || clientSecret.isBlank()) throw new IllegalArgumentException("Missing OAuth credentials");

Try / catch

try { client.createUserAccessToken(url, clientId, secret, code); } catch (IllegalStateException e) { log.error("Token exchange HTTP failure (see DEBUG body log)", e); throw e; }

Prevention

When it happens

Trigger: Calling createUserAccessToken(appUrl, clientId, clientSecret, code) when the POST response code != 200 — e.g. 404 from wrong appUrl, 5xx from GitHub, or 5xx/4xx at transport level.

Common situations: GitHub Enterprise URL misconfigured (endpoint path wrong), network outage, clientId/clientSecret pair invalid for that GitHub instance causing unexpected status handling differences.

Related errors


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