apache/seatunnel · warning · ElasticsearchConnectorException
DELETE_PIT_FAILED
DELETE_PIT_FAILED
Error message
DELETE /_pit response null
What it means
deletePointInTime closes a PIT context (DELETE /_pit with the pit id in the body); if performRequest returns null the client throws DELETE_PIT_FAILED. This happens at the end of a read; a null response means the cleanup request never got an HTTP answer, potentially leaving the PIT open on the server until keep_alive expires.
Source
Thrown at seatunnel-connectors-v2/connector-elasticsearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/elasticsearch/client/EsRestClient.java:966
}
}
/**
* Deletes a Point-in-Time (PIT).
*
* @param pitId The PIT ID to delete
* @return True if the PIT was successfully deleted
*/
public boolean deletePointInTime(String pitId) {
String endpoint = "/_pit";
Request request = new Request("DELETE", endpoint);
Map<String, String> requestBody = new HashMap<>();
requestBody.put("id", pitId);
request.setJsonEntity(JsonUtils.toJsonString(requestBody));
try {
Response response = restClient.performRequest(request);
if (response == null) {
throw new ElasticsearchConnectorException(
ElasticsearchConnectorErrorCode.DELETE_PIT_FAILED,
"DELETE " + endpoint + " response null");
}
String entity = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
JsonNode jsonNode = JsonUtils.parseObject(entity);
return jsonNode.get("succeeded").asBoolean();
} else {
throw new ElasticsearchConnectorException(
ElasticsearchConnectorErrorCode.DELETE_PIT_FAILED,
String.format(
"DELETE %s response status code=%d, body=%s",
endpoint, response.getStatusLine().getStatusCode(), entity));
}
} catch (IOException ex) {
throw new ElasticsearchConnectorException(
ElasticsearchConnectorErrorCode.DELETE_PIT_FAILED, ex);
}View on GitHub (pinned to cf67b549a7)
Solutions
- Ignore-and-retry is usually safe: the PIT auto-expires after keep_alive, so rerunning rarely causes resource exhaustion
- Check cluster for lingering PITs (GET /_nodes/stats) and wait for expiry or restart node if leaking
- Verify network stability for long-running jobs (idle TCP timeouts on LBs); tune keep-alive/TCP settings
- Fix any custom client wrapper that can return null instead of throwing
Defensive patterns
Strategy: fallback
Validate before calling
// ensure the PIT id is present before cleanup
if (pitId == null || pitId.isEmpty()) { skipDelete(); } Type guard
if (pitId == null || pitId.isEmpty()) { return; } // nothing to delete Try / catch
try {
esRestClient.deletePointInTime(pitId);
} catch (ElasticsearchConnectorException e) {
// cleanup is best-effort: log WARN, PIT expires via keep_alive
log.warn("PIT cleanup failed, will expire via keep_alive", e);
} Prevention
- Treat PIT deletion as best-effort cleanup, not a hard requirement
- Set keep_alive so leaked PITs expire quickly
- Avoid idle-connection-dropping proxies for long jobs
- Monitor open PIT contexts via /_nodes/stats to catch leaks
When it happens
Trigger: DELETE /_pit (body: {"id":"<pitId>"}) returning null Response from performRequest.
Common situations: Custom/mock RestClient returning null; connection already broken after a long read so the DELETE cannot be delivered; proxy dropping idle connections mid-job.
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
- CREATE_PIT_FAILED
- SEARCH_WITH_PIT_FAILED
- Failed to delete Point-in-Time with ID: {}
- BULK_RESPONSE_ERROR
- SCROLL_REQUEST_ERROR
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/c6f89451f662829f.
Report an issue: GitHub.