{"record":{"id":"a23dbed8cc43cda9","repo":"apache/seatunnel","slug":"binary-file-part-order-error","errorCode":"BINARY_FILE_PART_ORDER_ERROR","errorMessage":"Last order is \" + partIndexMap.get(filePath) + \", but get \" + partIndex","messagePattern":"Last order is \" \\+ partIndexMap\\.get\\(filePath\\) \\+ \", but get \" \\+ partIndex","errorType":"error_code","errorClass":"FileConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/writer/BinaryWriteStrategy.java","lineNumber":76,"sourceCode":"        if (!catalogTable.getSeaTunnelRowType().equals(BinaryReadStrategy.binaryRowType)) {\n            throw new FileConnectorException(\n                    FileConnectorErrorCode.FORMAT_NOT_SUPPORT,\n                    \"BinaryWriteStrategy only supports binary format, please read file with `BINARY` format, and do not change schema in the transform.\");\n        }\n    }\n\n    @Override\n    public void write(SeaTunnelRow seaTunnelRow) throws FileConnectorException {\n        long partIndex = (long) seaTunnelRow.getField(2);\n        if (partIndex == -1) {\n            return;\n        }\n        byte[] data = (byte[]) seaTunnelRow.getField(0);\n        String relativePath = (String) seaTunnelRow.getField(1);\n        String filePath = getOrCreateFilePathBeingWritten(relativePath);\n        FSDataOutputStream fsDataOutputStream = getOrCreateOutputStream(filePath);\n        if (partIndex - 1 != partIndexMap.get(filePath)) {\n            throw new FileConnectorException(\n                    FileConnectorErrorCode.BINARY_FILE_PART_ORDER_ERROR,\n                    \"Last order is \" + partIndexMap.get(filePath) + \", but get \" + partIndex);\n        } else {\n            partIndexMap.put(filePath, partIndex);\n        }\n        try {\n            fsDataOutputStream.write(data);\n        } catch (IOException e) {\n            throw CommonError.fileOperationFailed(\"BinaryFile\", \"write\", filePath, e);\n        }\n    }\n\n    public String getOrCreateFilePathBeingWritten(String relativePath) {\n        if (fileSinkConfig.isCustomFilename()) {\n            return getOrCreateCustomFilePathBeingWritten(relativePath);\n        }\n        String beingWrittenFilePath = beingWrittenFile.get(relativePath);\n        if (beingWrittenFilePath != null) {","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/writer/BinaryWriteStrategy.java#L58-L94","documentation":"Binary files are written as ordered parts; each row carries a part index that must arrive strictly in sequence per target file. BinaryWriteStrategy.write compares the incoming partIndex against the last recorded index for that output path and throws BINARY_FILE_PART_ORDER_ERROR when partIndex - 1 does not match the stored last index, i.e. a part is missing, duplicated, or out of order.","triggerScenarios":"Writing a binary row whose part index is not exactly previous_index + 1 for its relativePath — duplicated part index, a skipped part, or parts interleaved out of order from upstream.","commonSituations":"Upstream source/reader produced duplicate or out-of-order binary parts; parallel writers racing on the same relativePath; data replay after failure re-delivers an old part.","solutions":["Check the upstream binary source for duplicate or skipped part generation","Ensure the binary stream is not read/written with parallelism that can reorder parts of the same file","Verify the transform chain does not reprocess or replay rows; rebuild the job if replay delivered stale parts"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// validate incoming binary rows before writing\nlong expected = lastPartIndexForFile(relativePath) + 1;\nif (partIndex != expected) {\n  throw new IllegalStateException(\"Binary part out of order: expected \" + expected + \" got \" + partIndex);\n}","typeGuard":null,"tryCatchPattern":"try { write(row, partIndex); } catch (FileConnectorException e) {\n  if (e.getErrorCode().equals(FileConnectorErrorCode.BINARY_FILE_PART_ORDER_ERROR)) {\n    log.error(\"Binary part stream corrupted for file; abort and re-read source from the beginning\", e);\n    restartFromSource();\n  }\n}","preventionTips":["Ensure the upstream binary producer emits parts strictly sequentially per file","Avoid replaying or reprocessing binary rows after failure without resetting part indices","Do not parallelize writes of parts belonging to the same source file"],"tags":["file-sink","binary","ordering","data-corruption"],"backgroundTag":"internal-invariant-violation","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"}