SonarSource/sonarqube · error · IllegalStateException

Unsupported protocol in redirect of %s to %s

Error message

Unsupported protocol in redirect of %s to %s

What it means

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.

Source

Thrown at sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java:244

      // See:
      // https://github.com/square/okhttp/blob/07309c1c7d9e296014268ebd155ebf7ef8679f6c/okhttp/src/main/java/okhttp3/internal/http/RetryAndFollowUpInterceptor.java#L316
      // https://github.com/square/okhttp/issues/936#issuecomment-266430151
      return followPostRedirect(response, postRequest);
    } else {
      return response;
    }
  }

  private Response followPostRedirect(Response response, RequestWithPayload<?> postRequest) {
    String location = response.header("Location");
    if (location == null) {
      throw new IllegalStateException(format("Missing HTTP header 'Location' in redirect of %s", response.request().url()));
    }
    HttpUrl url = response.request().url().resolve(location);

    // Don't follow redirects to unsupported protocols.
    if (url == null) {
      throw new IllegalStateException(format("Unsupported protocol in redirect of %s to %s", response.request().url(), location));
    }

    Request.Builder redirectRequest = response.request().newBuilder();
    redirectRequest.post(response.request().body());
    response.body().close();
    return doCall(prepareOkHttpClient(noRedirectOkHttpClient, postRequest), redirectRequest.url(url).build());
  }

  /**
   * @since 5.5
   */
  public static Builder newBuilder() {
    return new Builder();
  }

  public static class Builder {
    private String url;
    private String userAgent;

View on GitHub (pinned to 184c821202)

Solutions

  1. Make the server redirect only to http:// or https:// URLs that HttpUrl can resolve
  2. Configure the client to call the final target URL directly, avoiding the redirect chain
  3. Fix or remove the middleware producing the malformed Location value

Example fix

// before: Location: custom-scheme://host/api
header('Location', 'custom-scheme://host/api');
// after
header('Location', 'https://host/api');
Defensive patterns

Strategy: try-catch

Try / catch

try {
  wsClient.post(request);
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Unsupported protocol in redirect")) {
    // call the intended https:// endpoint directly instead of following the redirect
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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'.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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