apache/seatunnel · warning
Malformed BATCH request, missing payload separator
Error message
Malformed BATCH request, missing payload separator: {} What it means
Logged by dispatchBatch() when a BATCH request contains no ':' separator after the command prefix, so the batch id cannot be separated from the payload. The server replies BAD_REQUEST. The wire format requires 'BATCH <id>:<payload>'.
Solutions
- Correct the collector to send 'BATCH <id>:<payload>' as a single newline-terminated line.
- Check collector serialization code to ensure the ':' separator and payload are written in the same frame.
- Compare client and server protocol versions.
Example fix
// before (client)
writer.write("BATCH " + id + "\n"); writer.write(payload);
// after
writer.write("BATCH " + id + ":" + payload + "\n"); Defensive patterns
Strategy: validation
Validate before calling
String cmd = "BATCH " + batchId + ":" + payload; if (!cmd.contains(":")) { throw new IllegalArgumentException("BATCH request missing ':' separator"); } Prevention
- Build the whole BATCH frame (id, separator, payload) in one helper and write it as a single line
- Never split id and payload across write calls that can be separated by flushes
- Add a unit test asserting the exact wire format
When it happens
Trigger: receiveLoop dispatches a line starting with the BATCH prefix that has no ':' following it — e.g. 'BATCH 12' or 'BATCH' with nothing else.
Common situations: Collector splitting id and payload onto separate lines instead of one, payload serialization dropping the separator, a truncated write due to network/buffer issues, client protocol version mismatch.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unrecognized command prefix, got
- Collector authentication failed from
- Command is not dispatched yet
- Invalid BATCH batchId in request
- Invalid COMMIT batchId in request
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/ef03c0d68a49896a.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-edge-socket/src/main/java/org/apache/seatunnel/connectors/seatunnel/edgesocket/protocol/IngressProtocolHandler.java:130
}
}
private String dispatchCommit(String request) {
Long batchId = parseBatchId(request, IngressCommand.COMMIT.prefix());
if (batchId == null || batchId <= 0) {
log.warn(
"Invalid COMMIT batchId in request: {}",
EdgeSocketLogUtils.abbreviateForLog(request));
return EdgeSocketResponseCode.INVALID_PARAM.getCode();
}
return handler.handleCommitRequest(batchId);
}
private String dispatchBatch(String request) {
int separatorIndex = request.indexOf(':', IngressCommand.BATCH.prefix().length());
if (separatorIndex < 0) {
log.warn(
"Malformed BATCH request, missing payload separator: {}",
EdgeSocketLogUtils.abbreviateForLog(request));
return EdgeSocketResponseCode.BAD_REQUEST.getCode();
}
Long batchId =
parseBatchId(request.substring(0, separatorIndex), IngressCommand.BATCH.prefix());
if (batchId == null || batchId <= 0) {
log.warn(
"Invalid BATCH batchId in request: {}",
EdgeSocketLogUtils.abbreviateForLog(request));
return EdgeSocketResponseCode.INVALID_PARAM.getCode();
}
String payload = request.substring(separatorIndex + 1);
return handler.handleBatchRecord(batchId, payload);
}
private static boolean constantTimeEquals(String expected, String actual) {
if (expected == null || actual == null) {
return Objects.equals(expected, actual);View on GitHub (pinned to cf67b549a7)