{"record":{"id":"0618438ccfd49eb8","repo":"SonarSource/sonarqube","slug":"interrupted-while-getting-a-token","errorCode":null,"errorMessage":"Interrupted while getting a token: ","messagePattern":"Interrupted while getting a token: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/sonar-server-common/src/main/java/org/sonar/server/oauth/OAuthMicrosoftRestClient.java","lineNumber":40,"sourceCode":"import com.github.scribejava.core.builder.ServiceBuilder;\nimport com.github.scribejava.core.oauth.OAuth20Service;\nimport java.io.IOException;\nimport java.util.concurrent.ExecutionException;\n\npublic class OAuthMicrosoftRestClient {\n\n  public String getAccessTokenFromClientCredentialsGrantFlow(String host, String clientId, String clientSecret, String tenant, String scope) {\n    final OAuth20Service service = new ServiceBuilder(clientId)\n      .apiSecret(clientSecret)\n      .defaultScope(scope)\n      .build(new ScribeMicrosoftOauth2Api(host, tenant));\n    try {\n      return service.getAccessTokenClientCredentialsGrant().getAccessToken();\n    } catch (IOException | ExecutionException e) {\n      throw new IllegalStateException(\"Unable to get a token: \" + e);\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new IllegalStateException(\"Interrupted while getting a token: \" + e);\n    }\n  }\n}\n","sourceCodeStart":22,"sourceCodeEnd":44,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-server-common/src/main/java/org/sonar/server/oauth/OAuthMicrosoftRestClient.java#L22-L44","documentation":"Same token-exchange flow as error 275, but the token request thread was interrupted while waiting for the OAuth response. The code restores the interrupt flag and throws IllegalStateException 'Interrupted while getting a token'.","triggerScenarios":"The thread executing getAccessTokenFromClientCredentialsGrantFlow is interrupted (shutdown, timeout watchdog) while awaiting Azure AD's token response.","commonSituations":"Server shutdown mid-request; SonarQube request/thread timeouts; container orchestration terminating the process during a slow token call.","solutions":["Investigate why the thread was interrupted (shutdown, executor timeout) and allow more time or retry the token request.","Check Azure AD latency/proxy delays causing slow responses that hit timeouts.","Ensure the interruption is not caused by a misconfigured timeout in the HTTP client; raise it if the network is slow.","Retry the operation after confirming the service is not shutting down."],"exampleFix":"// before\nExecutorService pool = Executors.newFixedThreadPool(1);\npool.shutdownNow(); // interrupts in-flight token request\n// after\npool.shutdown();\npool.awaitTermination(30, TimeUnit.SECONDS);","handlingStrategy":"retry","validationCode":"// ensure the calling thread won't be interrupted mid-exchange\nif (Thread.currentThread().isInterrupted()) { throw new IllegalStateException(\"Thread already interrupted; skip token exchange\"); }","typeGuard":null,"tryCatchPattern":"try { return oauthClient.getAccessTokenFromClientCredentialsGrantFlow(); } catch (IllegalStateException e) { if (e.getMessage().startsWith(\"Interrupted\")) { Thread.currentThread().interrupt(); throw new RetriableException(e); } throw e; }","preventionTips":["Avoid shutdownNow() on threads doing token exchanges","Give long-running OAuth calls enough timeout headroom","Use graceful shutdown with awaitTermination","Retry interrupted token exchanges once the system is stable"],"tags":["oauth","azure","interruption","concurrency"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}