{"record":{"id":"4fe9de2ac5ccedd8","repo":"SonarSource/sonarqube","slug":"unsupported-protocol-in-redirect-of-s-to-s","errorCode":null,"errorMessage":"Unsupported protocol in redirect of %s to %s","messagePattern":"Unsupported protocol in redirect of (.+?) to (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java","lineNumber":244,"sourceCode":"      // See:\n      // https://github.com/square/okhttp/blob/07309c1c7d9e296014268ebd155ebf7ef8679f6c/okhttp/src/main/java/okhttp3/internal/http/RetryAndFollowUpInterceptor.java#L316\n      // https://github.com/square/okhttp/issues/936#issuecomment-266430151\n      return followPostRedirect(response, postRequest);\n    } else {\n      return response;\n    }\n  }\n\n  private Response followPostRedirect(Response response, RequestWithPayload<?> postRequest) {\n    String location = response.header(\"Location\");\n    if (location == null) {\n      throw new IllegalStateException(format(\"Missing HTTP header 'Location' in redirect of %s\", response.request().url()));\n    }\n    HttpUrl url = response.request().url().resolve(location);\n\n    // Don't follow redirects to unsupported protocols.\n    if (url == null) {\n      throw new IllegalStateException(format(\"Unsupported protocol in redirect of %s to %s\", response.request().url(), location));\n    }\n\n    Request.Builder redirectRequest = response.request().newBuilder();\n    redirectRequest.post(response.request().body());\n    response.body().close();\n    return doCall(prepareOkHttpClient(noRedirectOkHttpClient, postRequest), redirectRequest.url(url).build());\n  }\n\n  /**\n   * @since 5.5\n   */\n  public static Builder newBuilder() {\n    return new Builder();\n  }\n\n  public static class Builder {\n    private String url;\n    private String userAgent;","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java#L226-L262","documentation":"After reading the 'Location' header of a redirect response, followPostRedirect() resolves it against the original request URL with okhttp3.HttpUrl.resolve(). If the result is null — typically because the location uses a scheme OkHttp does not support (e.g. a custom protocol) or is unparseable — the connector refuses to follow it and throws this IllegalStateException, guarding against redirects to unsupported protocols.","triggerScenarios":"A POST redirect's Location header points to a URL OkHttp cannot resolve/parse (unsupported scheme such as ftp://, custom scheme, or malformed URL) so HttpUrl.resolve(location) returns null.","commonSituations":"Proxy or gateway redirecting to a non-HTTP scheme; hand-rolled redirect handlers emitting relative paths OkHttp cannot resolve in context; typos in Location values like 'http:example.com'.","solutions":["Make the server redirect only to http:// or https:// URLs that HttpUrl can resolve","Configure the client to call the final target URL directly, avoiding the redirect chain","Fix or remove the middleware producing the malformed Location value"],"exampleFix":"// before: Location: custom-scheme://host/api\nheader('Location', 'custom-scheme://host/api');\n// after\nheader('Location', 'https://host/api');","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  wsClient.post(request);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Unsupported protocol in redirect\")) {\n    // call the intended https:// endpoint directly instead of following the redirect\n  } else {\n    throw e;\n  }\n}","preventionTips":["Ensure servers redirect only to http/https URLs","Audit reverse-proxy rewrite rules for Location header generation","Point the client directly at the canonical endpoint to eliminate redirects"],"tags":["http","redirect","url","network"],"backgroundTag":"invalid-url","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"}