apache/druid · error

Error reading response

Error message

Error reading response

What it means

When updating a lookup node via HTTP POST, a non-success response is received. The coordinator tries to read the response body for the error message; if reading the stream itself throws IOException, it logs a warning that the error response could not be read, then still throws an IOException describing the failed update.

Solutions

  1. Check connectivity and health of the target lookup node URL.
  2. Inspect lookup node logs for why the update returned a bad status.
  3. Retry the lookup update; the management loop will retry on the next cycle.
Defensive patterns

Strategy: retry

Validate before calling

// pre-check node health before update
int code = httpGetStatus(nodeUrl + "/status/health");
if (code != 200) throw new SkipUpdateException(nodeUrl);

Try / catch

try { updateNode(url, lookups); } catch (IOException e) { LOG.warn("lookup update to %s failed, will retry next cycle", url, e); }

Prevention

When it happens

Trigger: updateNode() POSTs to a lookup node and receives a bad HTTP status; StreamUtils.copyAndClose fails reading the error body (connection reset, stream closed).

Common situations: Lookup node under load resets connections; node crashed mid-response; network interruption between coordinator and node; wrong port/URL hitting a different service.

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/3052615baea8c80e. Report an issue: GitHub.

Appendix: source

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

                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())
          );
        }
      }
    }

    public LookupsState<LookupExtractorFactoryMapContainer> getLookupStateForNode(
        HostAndPortWithScheme node
    ) throws IOException, InterruptedException, ExecutionException
    {
      final URL url = getLookupsURL(node);

View on GitHub (pinned to 9b90983fd2)