apache/seatunnel · info
Attempted to clear scroll with empty scroll ID
Error message
Attempted to clear scroll with empty scroll ID
What it means
Guard in EsRestClient.clearScroll: called with a null or empty scrollId, so the client logs a warning and returns false without issuing any DELETE to Elasticsearch. Clearing a scroll with no ID is meaningless — the method short-circuits to avoid a pointless HTTP round trip. The scroll simply remains uncleared (a resource leak if the ID was lost).
Solutions
- Capture the scroll ID from the initial search response before any code path can lose it
- Skip clearScroll when no ID exists instead of treating false as an error: if (scrollId != null) client.clearScroll(scrollId)
- Trace why the ID was empty — check whether the initial search actually used scroll and succeeded
- On close paths, only clear scrolls that were actually opened (track them in a set)
Example fix
// before
boolean cleared = esClient.clearScroll(scrollId);
// after
if (scrollId != null && !scrollId.isEmpty()) {
boolean cleared = esClient.clearScroll(scrollId);
} Defensive patterns
Strategy: validation
Validate before calling
boolean shouldClear = scrollId != null && !scrollId.isEmpty();
Type guard
boolean hasScrollId(String id) { return id != null && !id.isEmpty(); } Prevention
- Capture scroll IDs at the point the scroll search succeeds
- Only register cleanup for scrolls actually opened
- Treat clearScroll==false without an ID as a no-op, not an error
- Null-check before close-time cleanup loops
When it happens
Trigger: clearScroll(scrollId) invoked with null or "" — typically the scroll ID was never captured from a search response, or the search that created it never ran/failed before returning an ID.
Common situations: Search path returned no scroll ID on an empty or failed initial search but cleanup still runs in finally; code path that clears scrolls on close even when scrolling was disabled; refactoring changed how the ID is passed and it is now dropped.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- DELETE response null for scroll ID
- DELETE response status code= , body= for scroll ID
- Failed to clear scroll ID
- Failed to clear scroll ID
- SCROLL_REQUEST_ERROR
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/d1e450d27c42c683.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-elasticsearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/elasticsearch/client/EsRestClient.java:312
return getDocsFromScrollRequest("/_search/scroll", JsonUtils.toJsonString(param));
}
public ScrollResult searchWithSql(String scrollId, JsonNode columnNodes) {
Map<String, String> param = new HashMap<>();
param.put("cursor", scrollId);
String endpoint = "/_sql?format=json";
return getDocsFromSqlResult(endpoint, JsonUtils.toJsonString(param), columnNodes);
}
/**
* Clear scroll context to release server-side resources.
*
* @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);View on GitHub (pinned to cf67b549a7)