{"record":{"id":"c4ccd231afc430f8","repo":"SonarSource/sonarqube","slug":"connection-to-azure-marketplace-failed-details","errorCode":null,"errorMessage":"Connection to Azure marketplace failed. Details: ${e.message}","messagePattern":"Connection to Azure marketplace failed\\. Details: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/azurebilling/service/DefaultAzureBillingHandler.java","lineNumber":119,"sourceCode":"    return azureEnvironment.getPlanId()\n      .orElseThrow(() -> new IllegalStateException(\"Azure Plan ID is not configured\"));\n  }\n\n  @NotNull\n  private ResponseEntity<AzureBillingRestResponse> handleAzureBillingRequest(Request request) {\n    try (Response response = client.newCall(request).execute()) {\n      if (response.isSuccessful()) {\n        return ResponseEntity.status(HttpStatus.OK).body(new AzureBillingRestResponse(true, null));\n      } else {\n        Optional<String> errorMessage = azureBillingResponseHandler.getErrorMessageFromResponse(response);\n        String errorMessageValue = errorMessage.orElse(response.message());\n\n        logError(errorMessageValue);\n        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new AzureBillingRestResponse(false, \"Call to Azure marketplace failed. Details: \" + errorMessageValue));\n      }\n    } catch (IOException e) {\n      logError(e.getMessage());\n      return ResponseEntity.status(500).body(new AzureBillingRestResponse(false, \"Connection to Azure marketplace failed. Details: \" + e.getMessage()));\n    }\n  }\n\n  private static void logError(String message) {\n    LOG.error(\"Error while billing Azure account: {}\", message);\n  }\n\n}\n","sourceCodeStart":101,"sourceCodeEnd":128,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/azurebilling/service/DefaultAzureBillingHandler.java#L101-L128","documentation":"DefaultAzureBillingHandler.handleAzureBillingRequest calls the Azure marketplace billing API; any IOException from that HTTP interaction (connection failure, DNS failure, TLS error, reset connection) is caught and converted into an HTTP 500 response whose body is AzureBillingRestResponse(false, \"Connection to Azure marketplace failed. Details: \" + e.getMessage()). The exception message is logged via logError and surfaced to the caller.","triggerScenarios":"The server cannot reach the Azure marketplace endpoint during billAzureAccount — network outage, DNS resolution failure, TLS handshake problem, connection reset/timeout producing IOException.","commonSituations":"Server egress firewall blocking the Azure marketplace host; transient network blips; misconfigured proxy; Azure-side incident interrupting connectivity.","solutions":["Check server egress connectivity to the Azure marketplace host (curl/DNS from the SonarQube server) and fix firewall/proxy rules","Retry the billing operation if the failure was transient","Inspect server logs ('Error while billing Azure account: ...') for the underlying IOException message","Verify TLS truststore/proxy configuration if details indicate handshake or unknown-host failures"],"exampleFix":"// before: no retry, raw 500\nreturn ResponseEntity.status(500).body(new AzureBillingRestResponse(false, \"Connection to Azure marketplace failed. Details: \" + e.getMessage()));\n// after: bounded retry for transient IO failures\ntry {\n  return doCall();\n} catch (IOException e) {\n  if (isTransient(e) && attempt < MAX_RETRIES) { backoff(); return doCall(); }\n  return ResponseEntity.status(500).body(new AzureBillingRestResponse(false, \"Connection to Azure marketplace failed. Details: \" + e.getMessage()));\n}","handlingStrategy":"try-catch","validationCode":"// shell: preflight connectivity to Azure marketplace from the server host\ncurl -sf --max-time 10 https://marketplaceapi.microsoft.com/api/ >/dev/null \\\n  || echo \"Azure marketplace unreachable from this host\"","typeGuard":null,"tryCatchPattern":"try {\n  ResponseEntity<AzureBillingRestResponse> resp = handler.billAzureAccount(request);\n  if (resp.getStatusCode().is5xxServerError()) {\n    // network failure to Azure marketplace; check resp.getBody() message and retry later\n  }\n} catch (RestClientException e) {\n  // transport-level failure calling the web API\n}","preventionTips":["Verify egress firewall/proxy rules allow the SonarQube server to reach the Azure marketplace host","Monitor DNS and TLS health on the server hosting billing calls","Add bounded retries with backoff for transient IOExceptions","Alert on 'Connection to Azure marketplace failed' log entries"],"tags":["network","azure","billing","http"],"backgroundTag":"network-request-failed","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}