apache/kafka · error · IllegalArgumentException
Invalid serialized transaction state format: {serializedStat
Error message
Invalid serialized transaction state format: {serializedState} What it means
Thrown by the PreparedTxnState(String) constructor when the input cannot be parsed into the expected 'producerId:epoch' shape. It fires both when the split-on-colon array does not have exactly two elements and when either token fails Long.parseLong/Short.parseShort (NumberFormatException is caught and re-thrown as this IllegalArgumentException).
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/producer/PreparedTxnState.java:67
return;
}
try {
String[] parts = serializedState.split(":");
if (parts.length != 2) {
throw new IllegalArgumentException("Invalid serialized transaction state format: " + serializedState);
}
this.producerId = Long.parseLong(parts[0]);
this.epoch = Short.parseShort(parts[1]);
// Validate the producerId and epoch values.
if (!(this.producerId >= 0 && this.epoch >= 0)) {
throw new IllegalArgumentException("Invalid producer ID and epoch values: " +
producerId + ":" + epoch + ". Both must be >= 0");
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid serialized transaction state format: " + serializedState, e);
}
}
/**
* Creates a new PreparedTxnState with the given producer ID and epoch
*
* @param producerId The producer ID
* @param epoch The producer epoch
*/
PreparedTxnState(long producerId, short epoch) {
this.producerId = producerId;
this.epoch = epoch;
}
/**
* Gets the producer ID associated with this prepared transaction state.
*
* @return The producer IDView on GitHub (pinned to c31c9215e1)
Solutions
- Verify the string matches the `producerId:epoch` format produced by PreparedTxnState.toString() before deserializing.
- Pass null or the empty string when no transaction is in flight — those are handled as 'uninitialized' and will not throw.
- Sanitize/validate the persisted state on write and treat a malformed entry as 'no transaction' instead of feeding it to the constructor.
Example fix
// before
new PreparedTxnState(rawFromStore) // rawFromStore = "id=7;epoch=0"
// after
if (rawFromStore == null || rawFromStore.isEmpty() || !rawFromStore.matches("\\d+:\\d+")) {
state = new PreparedTxnState("");
} else {
state = new PreparedTxnState(rawFromStore);
} Defensive patterns
Strategy: validation
Validate before calling
// Regex-check the serialized form BEFORE constructing PreparedTxnState.
static boolean isWellFormedSerializedTxnState(String s) {
if (s == null || s.isEmpty()) return true;
// Format is exactly '<long>:<short>', no sign, no whitespace.
return s.matches("\\d+:\\d+");
}
// Caller:
if (!isWellFormedSerializedTxnState(stored)) { /* reject / re-init */ } Try / catch
try {
PreparedTxnState state = new PreparedTxnState(userSupplied);
} catch (IllegalArgumentException e) {
// Covers both 'Invalid serialized transaction state format' and the
// negative-value (260) case — handle identically as corrupt input.
state = new PreparedTxnState();
} Prevention
- Never accept user-typed transaction state strings without a format check.
- Round-trip test any persistence layer: toString() -> constructor must never throw.
- Keep a single helper that both validates and parses so the format contract lives in one place.
When it happens
Trigger: Calling `new PreparedTxnState("abc")` (only one part), `new PreparedTxnState("a:b")` (non-numeric), `new PreparedTxnState("1:2:3")` (three parts), or any string that is not empty/null yet is not strictly two numeric tokens separated by a single ':'.
Common situations: Loading producer state from an external store whose schema drifted, manually constructing the string with a stray colon or whitespace, locale-specific formatting that inserted extra separators, or reading a stale state file written by an older format.
Related errors
- Invalid producer ID and epoch values: {producerId}:{epoch}.
- Cannot set transaction.timeout.ms when transaction.two.phase
- Must set retries to non-zero when using the idempotent produ
- Cannot set a transactional.id without also enabling idempote
- Invalid value null for configuration key.serializer: must be
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/26cfa72881e2ce13.json.
Report an issue: GitHub.