SonarSource/sonarqube · error · IllegalStateException
Cannot obtain Azure Access Token. Details:
Error message
Cannot obtain Azure Access Token. Details:
What it means
Thrown when the Azure token exchange HTTP call completes but returns a non-success status; the handler raises IllegalStateException embedding Azure's error message, which surfaces as a 500 from the billing endpoint.
Solutions
- Read the 'Details' suffix in the exception message for the exact Azure error (auth failure, throttling, etc.)
- Verify the Azure subscription is active and linked correctly in SonarCloud/Azure Marketplace
- Retry later if the details indicate throttling or a transient Azure error
- Check the configured Azure resource ID / environment matches your subscription
- Upgrade SonarQube if Azure changed its API contract
Example fix
// before
throw new IllegalStateException("Cannot obtain Azure Access Token. Details: " + response.message());
// after
if (response.code() == 429) {
throw new IllegalStateException("Azure rate limit hit, retry later. Details: " + response.message());
}
throw new IllegalStateException("Cannot obtain Azure Access Token. Details: " + response.message()); Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the Azure subscription is active/linked before billing; Azure itself will // reject the token exchange otherwise. // e.g. check subscription state via the Azure API: state === 'Active'
Type guard
null
Try / catch
try {
await billAzureAccount(subscriptionId);
} catch (err) {
const details = (err.message || '').split('Details:')[1];
if (details && /401|403|Unauthorized/i.test(details)) {
// fix Azure Marketplace subscription linkage/credentials
} else if (details && /429|throttl/i.test(details)) {
// retry later with backoff
} else { throw err; }
} Prevention
- Read the Details suffix to identify the exact Azure rejection reason
- Keep the Azure Marketplace subscription active and correctly linked
- Back off and retry on throttling responses
- Monitor Azure status pages for ongoing incidents
When it happens
Trigger: billAzureAccount flow: azureBillingCaller returns a response whose status is not the expected success code (e.g. 401/403/429/5xx from the Azure billing endpoint).
Common situations: Invalid or revoked Azure Marketplace subscription credentials, expired subscription, Azure throttling the request, Azure outage, wrong resource/tenant configuration.
Related errors
- Cannot extract Azure Access Token from response
- Can not get Bitbucket user profile. HTTP code
- Fail to execute request
- For security reasons, OAuth authentication should use…
- Interrupted while getting a token:
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/723305073adfde6e.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/azurebilling/service/DefaultAzureBillingHandler.java:87
String clientId = azureEnvironment.getAzureClientId()
.orElseThrow(() -> new IllegalStateException("Azure Client ID is not configured"));
Request tokenRequest = azureBillingRequestBuilder.getAzureUserTokenRequest(clientId);
try (Response response = client.newCall(tokenRequest).execute()) {
if (response.isSuccessful()) {
Optional<String> accessToken = azureBillingResponseHandler.extractAccessTokenFromResponse(response);
if (accessToken.isPresent()) {
return accessToken.get();
} else {
logError("Cannot extract Azure Access Token from response.");
throw new IllegalStateException("Cannot extract Azure Access Token from response");
}
} else {
logError(response.message());
throw new IllegalStateException("Cannot obtain Azure Access Token. Details: " + response.message());
}
} catch (IOException e) {
logError(e.getMessage());
throw new IllegalStateException("Cannot obtain Azure Access Token. Details: " + e.getMessage());
}
}
private String getResourceId() {
return azureEnvironment.getResourceId()
.orElseThrow(() -> new IllegalStateException("Azure Resource ID is not configured"));
}
private String getPlanId() {
return azureEnvironment.getPlanId()
.orElseThrow(() -> new IllegalStateException("Azure Plan ID is not configured"));
}
@NotNullView on GitHub (pinned to 184c821202)