{"record":{"id":"c8bbc2eb47a8df02","repo":"alibaba/DataX","slug":"failed-to-flush-data-to-doris-error-could-not-get","errorCode":null,"errorMessage":"Failed to flush data to Doris, Error could not get the final state of label[%s].\n","messagePattern":"Failed to flush data to Doris, Error could not get the final state of label\\[(.+?)\\]\\.\n","errorType":"http","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"doriswriter/src/main/java/com/alibaba/datax/plugin/writer/doriswriter/DorisStreamLoadObserver.java","lineNumber":97,"sourceCode":"    }\n\n    private void checkStreamLoadState(String host, String label) throws IOException {\n        int idx = 0;\n        while(true) {\n            try {\n                TimeUnit.SECONDS.sleep(Math.min(++idx, 5));\n            } catch (InterruptedException ex) {\n                break;\n            }\n            try (CloseableHttpClient httpclient = HttpClients.createDefault()) {\n                HttpGet httpGet = new HttpGet(new StringBuilder(host).append(\"/api/\").append(options.getDatabase()).append(\"/get_load_state?label=\").append(label).toString());\n                httpGet.setHeader(\"Authorization\", getBasicAuthHeader(options.getUsername(), options.getPassword()));\n                httpGet.setHeader(\"Connection\", \"close\");\n\n                try (CloseableHttpResponse resp = httpclient.execute(httpGet)) {\n                    HttpEntity respEntity = getHttpEntity(resp);\n                    if (respEntity == null) {\n                        throw new IOException(String.format(\"Failed to flush data to Doris, Error \" +\n                                \"could not get the final state of label[%s].\\n\", label), null);\n                    }\n                    Map<String, Object> result = (Map<String, Object>)JSON.parse(EntityUtils.toString(respEntity));\n                    String labelState = (String)result.get(\"data\");\n                    if (null == labelState) {\n                        throw new IOException(String.format(\"Failed to flush data to Doris, Error \" +\n                                \"could not get the final state of label[%s]. response[%s]\\n\", label, EntityUtils.toString(respEntity)), null);\n                    }\n                    LOG.info(String.format(\"Checking label[%s] state[%s]\\n\", label, labelState));\n                    switch(labelState) {\n                        case LAEBL_STATE_VISIBLE:\n                        case LAEBL_STATE_COMMITTED:\n                            return;\n                        case RESULT_LABEL_PREPARE:\n                            continue;\n                        case RESULT_LABEL_ABORTED:\n                            throw new DorisWriterExcetion (String.format(\"Failed to flush data to Doris, Error \" +\n                                    \"label[%s] state[%s]\\n\", label, labelState), null, true);","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/alibaba/DataX/blob/80ec23d5c5328eb90ca364d2749e92dfaf44541e/doriswriter/src/main/java/com/alibaba/datax/plugin/writer/doriswriter/DorisStreamLoadObserver.java#L79-L115","documentation":"DorisStreamLoadObserver.checkStreamLoadState throws this IOException while polling a duplicate load label: the get_load_state HTTP call answered, but the response entity was null so no state could be parsed. It occurs after Doris reported the label already existed, while the observer retries with backoff (sleep capped at 5s per iteration) to learn whether that earlier load actually committed.","triggerScenarios":"A stream load response Status of 'Label Already Exists' (e.g. job retried after a timeout with the same labelPrefix) enters checkStreamLoadState; the subsequent GET /api/<db>/get_load_state?label=... returns 200 with a null entity, triggering this error. The FE being restarted mid-poll is a typical cause.","commonSituations":"Task-level retries reusing labels after network hiccups, FE leader re-election during the check, or a proxy stripping response bodies. Companion message with 'response[%s]' covers the parsed-but-null state case; this one is the null-entity case.","solutions":["Check FE health/stability at the time of the error (fe.audit/fe.log, leader elections).","Retry the DataX job — label state will resolve to VISIBLE/COMMITTED or the label will expire; ensure labelPrefix differs per retry if your wrapper reuses labels.","Ensure loadUrl points directly at FEs (not a body-stripping proxy) and the http_port is correct.","Verify in Doris (SHOW LOAD WHERE LABEL = '...') what final state the label reached before re-running."],"exampleFix":"// before: retrying a job with identical labelPrefix can hit label-exists polling\n\"labelPrefix\": \"datax_job_20240101\"\n// after: unique prefix per run\n\"labelPrefix\": \"datax_job_20240101_run2\"","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (IOException e) { if (e.getMessage().contains(\"could not get the final state of label\")) { wait briefly, then query SHOW LOAD WHERE LABEL = '<label>' and treat VISIBLE/COMMITTED as success before re-running; } }","preventionTips":["Make labelPrefix unique per run (append timestamp/job id) so retries never collide with old labels.","Before re-running a failed Doris job, check the label's final state in Doris to avoid duplicate loads."],"tags":["datax","doris","writer","stream-load","retry","idempotency"],"backgroundTag":null,"analyzedSha":"80ec23d5c5328eb90ca364d2749e92dfaf44541e","analyzedAt":"2026-08-14T15:33:51.187Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}