apache/cassandra · error · MarshalException
Invalid TxnId:
Error message
Invalid TxnId:
What it means
TxnIdUtf8Type's anonymous subtype validates that any non-empty string is parseable as an Accord TxnId via TxnId.tryParse. If the string is non-empty but cannot be parsed, validate throws MarshalException with the offending value appended to the message. This ensures only well-formed transaction identifiers are stored.
Solutions
- Only write TxnId values obtained from the Accord API (TxnId.toString/toIdent output)
- Fix whatever generated the malformed id — verify it round-trips through TxnId.tryParse
- Check cluster version consistency for Accord/transaction id format
- If data is already corrupt, delete/rewrite the offending rows
Example fix
// before
String id = someUserInput; // arbitrary text
session.execute("INSERT INTO txns (id, ...) VALUES (?, ...)", id, ...);
// after
if (TxnId.tryParse(id) == null) throw new IllegalArgumentException("not a TxnId: " + id);
session.execute("INSERT INTO txns (id, ...) VALUES (?, ...)", id, ...); Defensive patterns
Strategy: validation
Validate before calling
if (!str.isEmpty() && TxnId.tryParse(str) == null)
throw new IllegalArgumentException("not a valid TxnId: " + str); Try / catch
try {
txnIdType.validate(value, accessor);
} catch (MarshalException e) {
log.error("Rejecting malformed TxnId: {}", e.getMessage());
} Prevention
- Only store ids produced by TxnId.toString/toIdent
- Round-trip-check ids with TxnId.tryParse before persisting
- Keep Accord-related formats consistent across cluster versions
When it happens
Trigger: Writing or comparing values against a txn-id-typed column where the string was not produced by TxnId.toString/toIdent — e.g. arbitrary text, truncated ids, or ids from an incompatible version.
Common situations: Application code inserting placeholder strings into Accord transaction-id columns; manual cqlsh inserts of copy-pasted/mangled ids; version mismatch where an older node writes ids a newer parser rejects (or vice versa).
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Accord transactions are disabled on table (table is being…
- Can only unset '" + name + "'
- Cannot mix auto and manual DC weights
- Cannot run accord only repair on
- Cannot run accord only repair on
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ae104273f0da2682.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/marshal/TxnIdUtf8Type.java:41
import org.apache.cassandra.cql3.functions.ArgumentDeserializer;
import org.apache.cassandra.serializers.MarshalException;
import org.apache.cassandra.serializers.TypeSerializer;
import org.apache.cassandra.serializers.UTF8Serializer;
import org.apache.cassandra.utils.ByteBufferUtil;
public class TxnIdUtf8Type extends PseudoUtf8Type
{
public static final TxnIdUtf8Type instance = new TxnIdUtf8Type();
static final TypeSerializer<String> txnIdSerializer = new UTF8Serializer()
{
@Override
public <V> void validate(V value, ValueAccessor<V> accessor) throws MarshalException
{
super.validate(value, accessor);
String str = deserialize(value, accessor);
if (!str.isEmpty() && null == TxnId.tryParse(str))
throw new MarshalException("Invalid TxnId: " + str);
}
};
private static final ArgumentDeserializer ARGUMENT_DESERIALIZER = new DefaultArgumentDeserializer(instance);
private static final ByteBuffer MASKED_VALUE = ByteBufferUtil.EMPTY_BYTE_BUFFER;
TxnIdUtf8Type() {} // singleton
String describe() { return "TxnId"; }
@Override
public TypeSerializer<String> getSerializer()
{
return txnIdSerializer;
}
@Override
public <VL, VR> int compareCustom(VL left, ValueAccessor<VL> accessorL, VR right, ValueAccessor<VR> accessorR)View on GitHub (pinned to 88fd0f6a0e)