{"record":{"id":"465a30cae65dcc3b","repo":"apache/seatunnel","slug":"bulk-response-error-465a30","errorCode":"BULK_RESPONSE_ERROR","errorMessage":"bulk es Response is null","messagePattern":"bulk es Response is null","errorType":"error_code","errorClass":"ElasticsearchConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-elasticsearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/elasticsearch/client/EsRestClient.java","lineNumber":129,"sourceCode":"        for (int i = 0; i < hosts.size(); i++) {\n            httpHosts[i] = HttpHost.create(hosts.get(i));\n        }\n\n        return RestClient.builder(httpHosts)\n                .setRequestConfigCallback(\n                        requestConfigBuilder ->\n                                requestConfigBuilder\n                                        .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)\n                                        .setSocketTimeout(SOCKET_TIMEOUT));\n    }\n\n    public BulkResponse bulk(String requestBody) {\n        Request request = new Request(\"POST\", \"/_bulk\");\n        request.setJsonEntity(requestBody);\n        try {\n            Response response = restClient.performRequest(request);\n            if (response == null) {\n                throw new ElasticsearchConnectorException(\n                        ElasticsearchConnectorErrorCode.BULK_RESPONSE_ERROR,\n                        \"bulk es Response is null\");\n            }\n            String entity = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);\n            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {\n                JsonNode json = OBJECT_MAPPER.readTree(entity);\n                int took = json.get(\"took\").asInt();\n                boolean errors = json.get(\"errors\").asBoolean();\n                return new BulkResponse(errors, took, entity);\n            } else {\n                throw new ElasticsearchConnectorException(\n                        ElasticsearchConnectorErrorCode.BULK_RESPONSE_ERROR,\n                        String.format(\n                                \"bulk es response status=%s, response body=%s, request body(truncate)=%s\",\n                                response.getStatusLine().getStatusCode(),\n                                entity,\n                                requestBody.substring(0, Math.min(1000, requestBody.length()))));\n            }","sourceCodeStart":111,"sourceCodeEnd":147,"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#L111-L147","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify Elasticsearch is reachable and the RestClient host/port/credentials are correct","Check network path (LB/proxy idle timeouts) and keep-alive settings; retry the bulk request","Catch ElasticsearchConnectorException with code BULK_RESPONSE_ERROR in the writer and retry with backoff","Upgrade/inspect the low-level RestClient setup; ensure no wrapper layer can return null"],"exampleFix":"// before\nBulkResponse resp = esRestClient.bulk(requestBody);\n// after\ntry {\n    BulkResponse resp = esRestClient.bulk(requestBody);\n} catch (ElasticsearchConnectorException e) {\n    if (ElasticsearchConnectorErrorCode.BULK_RESPONSE_ERROR.equals(e.getErrorCode())) {\n        retryBulk(requestBody);\n    } else { throw e; }\n}","handlingStrategy":"retry","validationCode":"boolean clientHealthy = esRestClient != null; // verify via a lightweight HEAD / ping before bulking","typeGuard":null,"tryCatchPattern":"try { client.bulk(body); } catch (ElasticsearchConnectorException e) { if (BULK_RESPONSE_ERROR.equals(e.getErrorCode())) retryWithBackoff(body); else throw e; }","preventionTips":["Keep connections alive and tune RestClient timeouts","Monitor cluster health before and during bulk writes","Avoid proxies that can drop the response without status"],"tags":["elasticsearch","bulk","null-response","rest-client"],"backgroundTag":"empty-response-body","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}