{"id":"26cfa72881e2ce13","repo":"apache/kafka","slug":"invalid-serialized-transaction-state-format-seri","errorCode":null,"errorMessage":"Invalid serialized transaction state format: {serializedState}","messagePattern":"Invalid serialized transaction state format: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/producer/PreparedTxnState.java","lineNumber":67,"sourceCode":"            return;\n        }\n\n        try {\n            String[] parts = serializedState.split(\":\");\n            if (parts.length != 2) {\n                throw new IllegalArgumentException(\"Invalid serialized transaction state format: \" + serializedState);\n            }\n\n            this.producerId = Long.parseLong(parts[0]);\n            this.epoch = Short.parseShort(parts[1]);\n\n            // Validate the producerId and epoch values.\n            if (!(this.producerId >= 0 && this.epoch >= 0)) {\n                throw new IllegalArgumentException(\"Invalid producer ID and epoch values: \" +\n                    producerId + \":\" + epoch + \". Both must be >= 0\");\n            }\n        } catch (NumberFormatException e) {\n            throw new IllegalArgumentException(\"Invalid serialized transaction state format: \" + serializedState, e);\n        }\n    }\n\n    /**\n     * Creates a new PreparedTxnState with the given producer ID and epoch\n     *\n     * @param producerId        The producer ID\n     * @param epoch             The producer epoch\n     */\n    PreparedTxnState(long producerId, short epoch) {\n        this.producerId = producerId;\n        this.epoch = epoch;\n    }\n\n    /**\n     * Gets the producer ID associated with this prepared transaction state.\n     *\n     * @return The producer ID","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/producer/PreparedTxnState.java#L49-L85","documentation":"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).","triggerScenarios":"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 ':'.","commonSituations":"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.","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."],"exampleFix":"// before\nnew PreparedTxnState(rawFromStore)  // rawFromStore = \"id=7;epoch=0\"\n\n// after\nif (rawFromStore == null || rawFromStore.isEmpty() || !rawFromStore.matches(\"\\\\d+:\\\\d+\")) {\n    state = new PreparedTxnState(\"\");\n} else {\n    state = new PreparedTxnState(rawFromStore);\n}","handlingStrategy":"validation","validationCode":"// Regex-check the serialized form BEFORE constructing PreparedTxnState.\nstatic boolean isWellFormedSerializedTxnState(String s) {\n    if (s == null || s.isEmpty()) return true;\n    // Format is exactly '<long>:<short>', no sign, no whitespace.\n    return s.matches(\"\\\\d+:\\\\d+\");\n}\n// Caller:\nif (!isWellFormedSerializedTxnState(stored)) { /* reject / re-init */ }","typeGuard":null,"tryCatchPattern":"try {\n    PreparedTxnState state = new PreparedTxnState(userSupplied);\n} catch (IllegalArgumentException e) {\n    // Covers both 'Invalid serialized transaction state format' and the\n    // negative-value (260) case — handle identically as corrupt input.\n    state = new PreparedTxnState();\n}","preventionTips":["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."],"tags":["kafka","producer","transactions","serialization","two-phase-commit"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}