apache/druid · error · IOException

Failed to parse update response from

Error message

Failed to parse update response from [%s]. response [%s]

What it means

updateNode() throws this IOException when the HTTP client successfully returns a 2xx response but parsing the response body (mapResponseHandler-style streaming read) fails with an IOException. Druid treats an unreadable success response from a lookup node's update endpoint as an error because the coordinator cannot confirm what the node applied.

Solutions

  1. Inspect lookup node logs around the same timestamp for handler errors or connection resets
  2. Check network path between coordinator and lookup nodes (proxies, LB timeouts)
  3. Retry the update — lookup propagation is retried by the management loop
  4. Ensure lookup node HTTP server versions are compatible and not emitting malformed responses
Defensive patterns

Strategy: retry

Try / catch

try {
  coordinator.updateNode(host, lookupMap);
} catch (IOException e) {
  if (e.getMessage().startsWith("Failed to parse update response")) {
    // transient body-read failure: retry with backoff
  }
}

Prevention

When it happens

Trigger: POSTing a lookup update to a lookup node's /lookup lookups endpoint and the response body stream throws IOException mid-read (connection reset while reading body, malformed chunked encoding, truncated response).

Common situations: Lookup nodes under load dropping connections mid-response, intermediary proxies/load balancers truncating responses, network flakiness in distributed clusters during lookup propagation.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

              .addHeader(HttpHeaders.Names.CONTENT_TYPE, SmileMediaTypes.APPLICATION_JACKSON_SMILE)
              .setContent(smileMapper.writeValueAsBytes(lookupsUpdate)),
          makeResponseHandler(returnCode, reasonString),
          lookupCoordinatorManagerConfig.getHostTimeout()
      ).get()) {
        if (httpStatusIsSuccess(returnCode.get())) {
          try {
            final LookupsState<LookupExtractorFactoryMapContainer> response = smileMapper.readValue(
                result,
                LOOKUPS_STATE_TYPE_REFERENCE
            );
            LOG.debug(
                "Update on [%s], Status: %s reason: [%s], Response [%s].", url, returnCode.get(), reasonString.get(),
                response
            );
            return response;
          }
          catch (IOException ex) {
            throw new IOE(ex, "Failed to parse update response from [%s]. response [%s]", url, result);
          }
        } else {
          final ByteArrayOutputStream baos = new ByteArrayOutputStream();
          try {
            StreamUtils.copyAndClose(result, baos);
          }
          catch (IOException e2) {
            LOG.warn(e2, "Error reading response");
          }

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

View on GitHub (pinned to 9b90983fd2)