apache/seatunnel · warning

Failed to close SQL cursor: {}

Error message

Failed to close SQL cursor: {}

What it means

In EsRestClient.closeSqlCursor, any exception thrown during the HTTP call to /_sql/close (connect timeout, socket timeout, IO error, parse failure) is caught, logged as this warning with the cursor id, and false is returned instead of propagating.

Source

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

            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) {
                throw new ElasticsearchConnectorException(
                        ElasticsearchConnectorErrorCode.SCROLL_REQUEST_ERROR,
                        "POST " + endpoint + " response null");
            }
            String entity = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                ObjectNode responseJson = JsonUtils.parseObject(entity);

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check network connectivity / proxy settings between the SeaTunnel worker and Elasticsearch
  2. Increase http connection and socket timeout settings
  3. Ensure TLS configuration is valid if https is used
  4. Treat as non-fatal: the cursor expires after its keep-alive period

Example fix

// before
// client throws/hides IO errors silently
// after
if (!esRestClient.closeSqlCursor(cursor)) {
    LOG.warn("Cursor {} not closed cleanly; it will expire after keep-alive", cursor);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check connectivity
// ensure ES host is reachable before job teardown relies on cursor close

Try / catch

try { client.closeSqlCursor(cursor); } catch (Exception e) { LOG.warn("cursor {} will expire naturally", cursor, e); }

Prevention

When it happens

Trigger: Network failure, connection refused, request timeout, or EntityUtils/JSON processing exception while POSTing to the /_sql/close endpoint.

Common situations: Elasticsearch temporarily unreachable at job shutdown; firewall dropping keep-alive connections; TLS misconfiguration; large timeouts causing socket timeouts.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/e0cebd19d9d223c4. Report an issue: GitHub.