{"record":{"id":"11d9e1aa9f7ba46e","repo":"apache/seatunnel","slug":"post-response-status-code-for-cursor","errorCode":null,"errorMessage":"POST {} response status code={} for cursor: {}","messagePattern":"POST (.+?) response status code=(.+?) for cursor: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-elasticsearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/elasticsearch/client/EsRestClient.java","lineNumber":378,"sourceCode":"        String endpoint = \"/_sql/close\";\n        Request request = new Request(\"POST\", endpoint);\n        Map<String, String> requestBody = new HashMap<>();\n        requestBody.put(\"cursor\", cursor);\n        request.setJsonEntity(JsonUtils.toJsonString(requestBody));\n\n        try {\n            Response response = restClient.performRequest(request);\n            if (response == null) {\n                log.warn(\"POST {} response null for cursor: {}\", endpoint, cursor);\n                return false;\n            }\n            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {\n                String entity = EntityUtils.toString(response.getEntity());\n                JsonNode jsonNode = JsonUtils.parseObject(entity);\n                return jsonNode.get(\"succeeded\").asBoolean();\n            } else {\n                log.warn(\n                        \"POST {} response status code={} for cursor: {}\",\n                        endpoint,\n                        response.getStatusLine().getStatusCode(),\n                        cursor);\n                return false;\n            }\n        } catch (Exception ex) {\n            log.warn(\"Failed to close SQL cursor: {}\", cursor, ex);\n            return false;\n        }\n    }\n\n    private ScrollResult getDocsFromSqlResult(\n            String endpoint, String requestBody, JsonNode columnNodes) {\n        Request request = new Request(\"POST\", endpoint);\n        request.setJsonEntity(requestBody);\n        try {\n            Response response = restClient.performRequest(request);\n            if (response == null) {","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-elasticsearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/elasticsearch/client/EsRestClient.java#L360-L396","documentation":"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.","triggerScenarios":"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.","commonSituations":"Cursor already closed/expired before close; cluster restarted between query and close; credentials lacking permission for /_sql/close; network proxy returning error status.","solutions":["Check the response status code in logs and verify the cursor id is still valid before closing","Verify credentials grant access to the _sql/close endpoint","Increase pit_keep_alive/sql cursor keep-alive so cursors don't expire before close","Ignore gracefully: this is a warning and returns false; cursor auto-expires after keep-alive"],"exampleFix":"// before\nboolean closed = esRestClient.closeSqlCursor(cursor); // assume success\n// after\nif (!esRestClient.closeSqlCursor(cursor)) {\n    log.info(\"cursor {} will expire via keep-alive; ignoring close failure\", cursor);\n}","handlingStrategy":"fallback","validationCode":"// validate cursor before close\nif (cursor != null && !cursor.isEmpty()) {\n    boolean closed = client.closeSqlCursor(cursor);\n    if (!closed) LOG.info(\"cursor close returned false; relying on keep-alive expiry\");\n}","typeGuard":"// Java: check cursor validity\njava.util.function.Predicate<String> validCursor = c -> c != null && !c.isEmpty();","tryCatchPattern":null,"preventionTips":["Always treat closeSqlCursor's boolean return as best-effort","Set adequate keep-alive so cursors outlive processing","Check ES credentials cover the _sql/close endpoint"],"tags":["elasticsearch","http","sql-cursor"],"backgroundTag":"http-error-response","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}