SonarSource/sonarqube · error · IllegalStateException
Missing HTTP header 'Location' in redirect of %s
Error message
Missing HTTP header 'Location' in redirect of %s
What it means
HttpConnector.followPostRedirect() re-issues POST requests after an HTTP 3xx redirect, but OkHttp is configured with noRedirectOkHttpClient so the connector must locate the redirect target itself via the 'Location' response header. When a redirect response arrives without that header, the connector cannot build the follow-up request and throws this IllegalStateException. It signals a malformed/non-conformant redirect from the server.
Source
Thrown at sonar-ws/src/main/java/org/sonarqube/ws/client/HttpConnector.java:238
}
private Response checkRedirect(Response response, RequestWithPayload<?> postRequest) {
if (List.of(HTTP_MOVED_PERM, HTTP_MOVED_TEMP, HTTP_TEMP_REDIRECT, HTTP_PERM_REDIRECT).contains(response.code())) {
// OkHttpClient does not follow the redirect with the same HTTP method. A POST is
// redirected to a GET. Because of that the redirect must be manually implemented.
// 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() {View on GitHub (pinned to 184c821202)
Solutions
- Fix the server/proxy so every 3xx response includes a valid 'Location' header
- Call the final (non-redirecting) URL directly to bypass the broken redirect
- Inspect the redirecting hop with curl -v and remove/reconfigure the middleware that produces the headerless redirect
Example fix
// before: server sends 302 without Location
res.writeHead(302); res.end();
// after
res.writeHead(302, { Location: '/session/new' }); res.end(); Defensive patterns
Strategy: try-catch
Try / catch
// before calling the WS client you cannot inspect headers, so catch at call site
try {
wsClient.post(request);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Missing HTTP header 'Location'")) {
// fall back to the final URL directly or surface a server/proxy misconfiguration
} else {
throw e;
}
} Prevention
- Verify proxies/gateways in front of SonarQube emit conformant 3xx responses with Location
- Prefer configuring the client with the final URL to avoid redirect chains
- Test redirect behavior with curl -i when routing changes are deployed
When it happens
Trigger: A POST through HttpConnector (doCall/checkRedirect path) receives an HTTP 301/302/303/307/308 response whose headers lack a 'Location' header, so response.header("Location") returns null.
Common situations: Reverse proxies or load balancers emitting incomplete 302 responses; custom server-side redirects that set status but forget Location; misconfigured SSO/auth redirects in front of SonarQube; HTTP intermediaries stripping the header.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Unsupported protocol in redirect of %s to %s
- SonarQube was not able to retrieve resources from external s
- Could not validate GitLab write permission. Got an unexpecte
- Could not parse GitLab answer when creating a project access
- Error while executing GraphQl query. Return code %s. Error m
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/54639290da11cd1a.
Report an issue: GitHub.