apache/seatunnel · warning

DELETE {} response null for scroll ID: {}

Error message

DELETE {} response null for scroll ID: {}

What it means

EsRestClient.clearScroll logs this when restClient.performRequest returns a null Response for the DELETE /_search/scroll request. The low-level REST client normally throws rather than returning null, so a null response indicates an abnormal/unexpected client state. clearScroll returns false, signaling the scroll was not cleared (possible server-side resource leak).

Source

Thrown at seatunnel-connectors-v2/connector-elasticsearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/elasticsearch/client/EsRestClient.java:325

     * @param scrollId The scroll ID to clear
     * @return True if the scroll was successfully cleared
     */
    public boolean clearScroll(String scrollId) {
        if (StringUtils.isEmpty(scrollId)) {
            log.warn("Attempted to clear scroll with empty scroll ID");
            return false;
        }

        String endpoint = "/_search/scroll";
        Request request = new Request("DELETE", endpoint);
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("scroll_id", scrollId);
        request.setJsonEntity(JsonUtils.toJsonString(requestBody));

        try {
            Response response = restClient.performRequest(request);
            if (response == null) {
                log.warn("DELETE {} response null for scroll ID: {}", endpoint, scrollId);
                return false;
            }
            String entity = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                JsonNode jsonNode = JsonUtils.parseObject(entity);
                boolean succeeded = jsonNode.get("succeeded").asBoolean();
                return succeeded;
            } else {
                log.warn(
                        "DELETE {} response status code={}, body={} for scroll ID: {}",
                        endpoint,
                        response.getStatusLine().getStatusCode(),
                        entity,
                        scrollId);
                return false;
            }
        } catch (Exception ex) {
            log.warn("Failed to clear scroll ID: " + scrollId, ex);

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Treat false from clearScroll as best-effort cleanup; scrolls also expire via the scroll timeout, so set a sane scroll timeout on searches
  2. Check RestClient configuration/proxy for wrappers that can return null responses instead of throwing
  3. Log/capture at the caller: verify cluster connectivity — a real transport problem usually throws instead
  4. Retry clearScroll once with the same scroll ID; clearing is idempotent
  5. Ensure scroll TTL (scroll timeout on the search) is bounded so leaked scrolls self-expire

Example fix

// before: assume response always non-null
Response r = restClient.performRequest(req);
// after: caller bounds scroll lifetime regardless
searchSourceBuilder.scroll(TimeValue.timeValueMinutes(1)); // expired scrolls self-free
esClient.clearScroll(scrollId); // best-effort
Defensive patterns

Strategy: fallback

Try / catch

// clearScroll is best-effort; don't fail the pipeline on cleanup
boolean cleared = esClient.clearScroll(scrollId);
if (!cleared) {
    log.info("Scroll {} cleanup unconfirmed; relying on scroll TTL expiry", scrollId);
}

Prevention

When it happens

Trigger: DELETE /_search/scroll executed and performRequest resolved to null — defensive branch for a client that returned no response object (connection layer anomaly, wrapped/mocked client).

Common situations: Custom or shaded RestClient wrapper that returns null instead of throwing on transport failure; testing stubs; edge conditions in the REST client where no response and no exception occur.

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/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/d96dd2239b2ba728. Report an issue: GitHub.