apache/seatunnel · error · ElasticsearchConnectorException

BULK_RESPONSE_ERROR

BULK_RESPONSE_ERROR

Error message

bulk es Response is null

What it means

EsRestClient.bulk sends a POST /_bulk request and expects an HTTP Response object. If restClient.performRequest returns null (no response object at all), it throws ElasticsearchConnectorException with code BULK_RESPONSE_ERROR. This guards downstream NPEs when reading status code and entity from the response.

Source

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

        for (int i = 0; i < hosts.size(); i++) {
            httpHosts[i] = HttpHost.create(hosts.get(i));
        }

        return RestClient.builder(httpHosts)
                .setRequestConfigCallback(
                        requestConfigBuilder ->
                                requestConfigBuilder
                                        .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                                        .setSocketTimeout(SOCKET_TIMEOUT));
    }

    public BulkResponse bulk(String requestBody) {
        Request request = new Request("POST", "/_bulk");
        request.setJsonEntity(requestBody);
        try {
            Response response = restClient.performRequest(request);
            if (response == null) {
                throw new ElasticsearchConnectorException(
                        ElasticsearchConnectorErrorCode.BULK_RESPONSE_ERROR,
                        "bulk es Response is null");
            }
            String entity = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                JsonNode json = OBJECT_MAPPER.readTree(entity);
                int took = json.get("took").asInt();
                boolean errors = json.get("errors").asBoolean();
                return new BulkResponse(errors, took, entity);
            } else {
                throw new ElasticsearchConnectorException(
                        ElasticsearchConnectorErrorCode.BULK_RESPONSE_ERROR,
                        String.format(
                                "bulk es response status=%s, response body=%s, request body(truncate)=%s",
                                response.getStatusLine().getStatusCode(),
                                entity,
                                requestBody.substring(0, Math.min(1000, requestBody.length()))));
            }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Verify Elasticsearch is reachable and the RestClient host/port/credentials are correct
  2. Check network path (LB/proxy idle timeouts) and keep-alive settings; retry the bulk request
  3. Catch ElasticsearchConnectorException with code BULK_RESPONSE_ERROR in the writer and retry with backoff
  4. Upgrade/inspect the low-level RestClient setup; ensure no wrapper layer can return null

Example fix

// before
BulkResponse resp = esRestClient.bulk(requestBody);
// after
try {
    BulkResponse resp = esRestClient.bulk(requestBody);
} catch (ElasticsearchConnectorException e) {
    if (ElasticsearchConnectorErrorCode.BULK_RESPONSE_ERROR.equals(e.getErrorCode())) {
        retryBulk(requestBody);
    } else { throw e; }
}
Defensive patterns

Strategy: retry

Validate before calling

boolean clientHealthy = esRestClient != null; // verify via a lightweight HEAD / ping before bulking

Try / catch

try { client.bulk(body); } catch (ElasticsearchConnectorException e) { if (BULK_RESPONSE_ERROR.equals(e.getErrorCode())) retryWithBackoff(body); else throw e; }

Prevention

When it happens

Trigger: POST /_bulk returning a null Response object from the low-level RestClient — normally caused by an abnormal connection state (connection closed, client misconfigured, or a mocked/failed transport) rather than a normal HTTP error.

Common situations: Broken or half-closed HTTP connections to Elasticsearch during bulk writes; RestClient misconfiguration (bad host list) causing performRequest to yield null in a wrapper; a proxy or load balancer silently terminating the request; unit/test harnesses returning null responses.

Related errors


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