apache/seatunnel · error · EasysearchConnectorException

SCROLL_REQUEST_ERROR

SCROLL_REQUEST_ERROR

Error message

POST ${endpoint} response null

What it means

EasysearchClient wraps the low-level REST client and throws EasysearchConnectorException with SCROLL_REQUEST_ERROR when a scroll POST returns a null Response object. The low-level RestClient.performRequest is expected to always return a Response or throw IOException, so a null is treated as a protocol-level anomaly and surfaced as a connector failure. This guards the caller from NPEs when dereferencing the status line.

Source

Thrown at seatunnel-connectors-v2/connector-easysearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/easysearch/client/EasysearchClient.java:372

     * @param scrollId the scroll id of the last request
     * @param scrollTime such as:1m
     */
    public ScrollResult searchWithScrollId(String scrollId, String scrollTime) {
        Map<String, String> param = new HashMap<>();
        param.put("scroll_id", scrollId);
        param.put("scroll", scrollTime);
        ScrollResult scrollResult =
                getDocsFromScrollRequest("/_search/scroll", JsonUtils.toJsonString(param));
        return scrollResult;
    }

    private ScrollResult getDocsFromScrollRequest(String endpoint, String requestBody) {
        Request request = new Request("POST", endpoint);
        request.setJsonEntity(requestBody);
        try {
            Response response = restClient.performRequest(request);
            if (response == null) {
                throw new EasysearchConnectorException(
                        EasysearchConnectorErrorCode.SCROLL_REQUEST_ERROR,
                        "POST " + endpoint + " response null");
            }
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String entity = EntityUtils.toString(response.getEntity());
                ObjectNode responseJson = JsonUtils.parseObject(entity);

                JsonNode shards = responseJson.get("_shards");
                int totalShards = shards.get("total").intValue();
                int successful = shards.get("successful").intValue();
                Asserts.check(
                        totalShards == successful,
                        String.format(
                                "POST %s,total shards(%d)!= successful shards(%d)",
                                endpoint, totalShards, successful));

                ScrollResult scrollResult = getDocsFromScrollResponse(responseJson);
                return scrollResult;

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check network/proxy configuration between SeaTunnel and the Easysearch/Elasticsearch node; a healthy client should throw IOException rather than return null
  2. Verify the endpoint URL built for scroll is valid (no malformed index or scroll_id)
  3. Upgrade/rebuild the connector so the shaded RestClient version matches the server
  4. Enable REST client trace logging (org.apache.http / RestClient) to capture the exchange preceding the null response

Example fix

// before
Response response = restClient.performRequest(request);
if (response == null) { throw new EasysearchConnectorException(...SCROLL_REQUEST_ERROR...); }
// after
Response response = restClient.performRequest(request);
Objects.requireNonNull(response, "scroll response must not be null");
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { /* retry with backoff */ }
Defensive patterns

Strategy: retry

Validate before calling

// verify cluster reachable before job
try (CloseableHttpResponse r = httpClient.execute(new HttpGet(baseUrl + "/_cluster/health"))) {
  if (r.getStatusLine().getStatusCode() != 200) throw new IllegalStateException("cluster unreachable");
}

Type guard

boolean valid(Response r) { return r != null && r.getStatusLine() != null; }

Try / catch

try { scrollResult(...); } catch (EasysearchConnectorException e) { if (e.getErrorCode() == SCROLL_REQUEST_ERROR) { backoffRetry(3); } else throw e; }

Prevention

When it happens

Trigger: getDocsFromScrollRequest is invoked via scrollResult when a scroll request is issued (first scroll with a query body or continuation scroll with scroll_id) and restClient.performRequest(request) unexpectedly returns null.

Common situations: Unusual proxy/interceptor behavior returning null, a broken or misconfigured node behind a load balancer that swallows the response, or misuse of a custom RestClient wrapper in tests.

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