apache/seatunnel · warning

POST response status code= for cursor

Error message

POST {} response status code={} for cursor: {}

What it means

EsRestClient.closeSqlCursor attempts to POST to the /_sql/close endpoint to release a server-side SQL cursor. If the response status is not 200 OK, this warn log is emitted and the method returns false; the cursor may remain open server-side until it times out.

Solutions

  1. Check the response status code in logs and verify the cursor id is still valid before closing
  2. Verify credentials grant access to the _sql/close endpoint
  3. Increase pit_keep_alive/sql cursor keep-alive so cursors don't expire before close
  4. Ignore gracefully: this is a warning and returns false; cursor auto-expires after keep-alive

Example fix

// before
boolean closed = esRestClient.closeSqlCursor(cursor); // assume success
// after
if (!esRestClient.closeSqlCursor(cursor)) {
    log.info("cursor {} will expire via keep-alive; ignoring close failure", cursor);
}
Defensive patterns

Strategy: fallback

Validate before calling

// validate cursor before close
if (cursor != null && !cursor.isEmpty()) {
    boolean closed = client.closeSqlCursor(cursor);
    if (!closed) LOG.info("cursor close returned false; relying on keep-alive expiry");
}

Type guard

// Java: check cursor validity
java.util.function.Predicate<String> validCursor = c -> c != null && !c.isEmpty();

Prevention

When it happens

Trigger: Calling closeSqlCursor when the Elasticsearch node returns a non-200 HTTP status (e.g. 400 bad cursor id, 401 auth failure, 404 no such cursor, 503 node unavailable) while closing a cursor created by a SQL query.

Common situations: Cursor already closed/expired before close; cluster restarted between query and close; credentials lacking permission for /_sql/close; network proxy returning error status.

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/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/11d9e1aa9f7ba46e. 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:378

        String endpoint = "/_sql/close";
        Request request = new Request("POST", endpoint);
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("cursor", cursor);
        request.setJsonEntity(JsonUtils.toJsonString(requestBody));

        try {
            Response response = restClient.performRequest(request);
            if (response == null) {
                log.warn("POST {} response null for cursor: {}", endpoint, cursor);
                return false;
            }
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String entity = EntityUtils.toString(response.getEntity());
                JsonNode jsonNode = JsonUtils.parseObject(entity);
                return jsonNode.get("succeeded").asBoolean();
            } else {
                log.warn(
                        "POST {} response status code={} for cursor: {}",
                        endpoint,
                        response.getStatusLine().getStatusCode(),
                        cursor);
                return false;
            }
        } catch (Exception ex) {
            log.warn("Failed to close SQL cursor: {}", cursor, ex);
            return false;
        }
    }

    private ScrollResult getDocsFromSqlResult(
            String endpoint, String requestBody, JsonNode columnNodes) {
        Request request = new Request("POST", endpoint);
        request.setJsonEntity(requestBody);
        try {
            Response response = restClient.performRequest(request);
            if (response == null) {

View on GitHub (pinned to cf67b549a7)