{"record":{"id":"d803b2a39169dfd3","repo":"alibaba/DataX","slug":"failed-to-flush-data-to-doris-error-label-s-sta","errorCode":null,"errorMessage":"Failed to flush data to Doris, Error label[%s] state[%s]\n","messagePattern":"Failed to flush data to Doris, Error label\\[(.+?)\\] state\\[(.+?)\\]\n","errorType":"http","errorClass":"DorisWriterExcetion","httpStatus":null,"severity":"error","filePath":"doriswriter/src/main/java/com/alibaba/datax/plugin/writer/doriswriter/DorisStreamLoadObserver.java","lineNumber":114,"sourceCode":"                    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);\n                        case RESULT_LABEL_UNKNOWN:\n                        default:\n                            throw new IOException(String.format(\"Failed to flush data to Doris, Error \" +\n                                    \"label[%s] state[%s]\\n\", label, labelState), null);\n                    }\n                }\n            }\n        }\n    }\n\n    private byte[] addRows(List<byte[]> rows, int totalBytes) {\n        if (Keys.StreamLoadFormat.CSV.equals(options.getStreamLoadFormat())) {\n            Map<String, Object> props = (options.getLoadProps() == null ? new HashMap<> () : options.getLoadProps());\n            byte[] lineDelimiter = DelimiterParser.parse((String)props.get(\"line_delimiter\"), \"\\n\").getBytes(StandardCharsets.UTF_8);\n            ByteBuffer bos = ByteBuffer.allocate(totalBytes + rows.size() * lineDelimiter.length);\n            for (byte[] row : rows) {\n                bos.put(row);","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/alibaba/DataX/blob/80ec23d5c5328eb90ca364d2749e92dfaf44541e/doriswriter/src/main/java/com/alibaba/datax/plugin/writer/doriswriter/DorisStreamLoadObserver.java#L96-L132","documentation":"The Doris FE reported the stream-load label's state as ABORTED. The load identified by 'label' definitively failed and was rolled back, so the observer throws DorisWriterExcetion with needReCreateLabel=true to signal the writer manager that a retry must mint a fresh label (Doris labels are single-use).","triggerScenarios":"flush() polls the label state; the FE returns state ABORTED (e.g. 'aborted' from the txn). Any load-time error — schema mismatch, BE failure, timeout, duplicate label — that makes the FE abort the transaction lands here. The writer manager catches it, generates a new label via createBatchLabel(), and retries up to maxRetries.","commonSituations":"Rerunning a job with the same labelPrefix after a partial failure (duplicate/aborted label); BE nodes crashed or out of disk during load; column count/type mismatch between data and Doris table causing BE to abort; load timeout (exec_mem_limit/streaming_label_timeout).","solutions":["Check FE audit/BE logs for why the transaction aborted; fix the root cause (schema, BE health, timeouts) rather than relying on retry","Use a unique labelPrefix per job run so retried loads never reuse an aborted label","If retryable (transient BE issue), increase maxRetries in the doriswriter job config so the manager's new-label retry loop can succeed","Verify the target table schema matches the data (column count, types, format CSV/JSON delimiters)"],"exampleFix":"// before\n\"labelPrefix\": \"datax_job1\",\n\"maxRetries\": 0\n// after: unique label per run and allow the built-in re-create-label retry\n\"labelPrefix\": \"datax_job1_${uuid}\",\n\"maxRetries\": 3","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (DorisWriterExcetion e) {\n    if (e.needReCreateLabel()) {\n        // manager already handles this: new label is minted and retried up to maxRetries\n        // ensure maxRetries >= 1 in job config so this path can succeed\n    }\n    throw e;\n}","preventionTips":["Always set a run-unique labelPrefix (append timestamp/uuid) so aborted labels are never reused","Set maxRetries to 2-3 so transient BE failures recover via the re-create-label retry loop","Pre-validate the target table schema (column count/types) with a 1-row dry load before the full job"],"tags":["doris","stream-load","transaction-aborted","retry"],"backgroundTag":null,"analyzedSha":"80ec23d5c5328eb90ca364d2749e92dfaf44541e","analyzedAt":"2026-08-14T15:33:51.187Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}