apache/druid · error · IOException

GET request failed to

Error message

GET request failed to [%s] : [%d] : [%s]  Response: [%s]

What it means

getLookupStateForNode() throws this IOException when the GET request for a node's lookup state returns a non-2xx HTTP status. The message includes the URL, status code, reason phrase, and any readable response body to diagnose why the node refused or failed the GET.

Solutions

  1. Check the status code and body in the exception: 404 implies wrong endpoint/version, 5xx implies node-side failure
  2. Ensure all nodes in the tier run a Druid version supporting the lookups endpoint
  3. Exclude nodes that are shutting down or fix the node experiencing 5xx errors
  4. If auth is enabled, verify coordinator credentials can access the lookup endpoint
Defensive patterns

Strategy: try-catch

Try / catch

try {
  state = coordinator.getLookupStateForNode(host);
} catch (IOException e) {
  if (e.getMessage().startsWith("GET request failed")) {
    int code = parseStatusCode(e.getMessage());
    if (code == 404) { /* node too old / wrong endpoint */ }
    else if (code >= 500) { /* node-side failure: retry later */ }
  }
}

Prevention

When it happens

Trigger: GET of /druid/listen/v1/lookups on a node returning 404 (node lacks the endpoint), 503 (node shutting down), 500 (server error), or auth rejection (401/403 when authentication is enabled).

Common situations: Querying nodes that don't host the lookups API (version skew or wrong tier/service), node mid-restart during rolling deploys, authentication misconfiguration between coordinator and nodes.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/34fddfe981a036ce. Report an issue: GitHub.

Appendix: source

Thrown at server/src/main/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManager.java:880

                returnCode.get(),
                reasonString.get(),
                response
            );
            return response;
          }
          catch (IOException ex) {
            throw new IOE(ex, "Failed to parser GET lookups response from [%s]. response [%s].", url, result);
          }
        } else {
          final ByteArrayOutputStream baos = new ByteArrayOutputStream();
          try {
            StreamUtils.copyAndClose(result, baos);
          }
          catch (IOException ex) {
            LOG.warn(ex, "Error reading response from GET on url [%s]", url);
          }

          throw new IOE(
              "GET request failed to [%s] : [%d] : [%s]  Response: [%s]",
              url,
              returnCode.get(),
              reasonString.get(),
              StringUtils.fromUtf8(baos.toByteArray())
          );
        }
      }
    }

    @VisibleForTesting
    HttpResponseHandler<InputStream, InputStream> makeResponseHandler(
        final AtomicInteger returnCode,
        final AtomicReference<String> reasonString
    )
    {
      return new SequenceInputStreamResponseHandler()
      {

View on GitHub (pinned to 9b90983fd2)