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

  1. Only write TxnId values obtained from the Accord API (TxnId.toString/toIdent output)
  2. Fix whatever generated the malformed id — verify it round-trips through TxnId.tryParse
  3. Check cluster version consistency for Accord/transaction id format
  4. 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

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


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)