apache/pulsar · error · InvalidTxnStatusException
Transaction recover tracker`
Error message
Transaction recover tracker`
What it means
TransactionRecoverTrackerImpl.updateTransactionStatus replays entries from the transaction log and applies COMMITTING/ABORTING/COMMITTED/ABORTED status changes. It throws InvalidTxnStatusException when the replayed operation/status is unknown, indicating the transaction log contains metadata this tracker cannot interpret. This is a fail-fast guard so a corrupt or foreign log entry does not silently misstate a transaction's status.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/recover/TransactionRecoverTrackerImpl.java:106
@Override
public void updateTransactionStatus(long sequenceId, TxnStatus txnStatus) throws InvalidTxnStatusException {
switch (txnStatus) {
case COMMITTING:
openTransactions.remove(sequenceId);
committingTransactions.add(sequenceId);
break;
case ABORTING:
openTransactions.remove(sequenceId);
abortingTransactions.add(sequenceId);
break;
case ABORTED:
abortingTransactions.remove(sequenceId);
break;
case COMMITTED:
committingTransactions.remove(sequenceId);
break;
default:
throw new InvalidTxnStatusException("Transaction recover tracker`"
+ new TxnID(tcId, sequenceId) + "` load replay metadata operation "
+ "from transaction log with unknown operation");
}
}
@Override
public void handleOpenStatusTransaction(long sequenceId, long timeout) {
openTransactions.put(sequenceId, timeout);
}
@Override
public void appendOpenTransactionToTimeoutTracker() {
openTransactions.forEach(timeoutTracker::replayAddTransaction);
}
@Override
public void handleCommittingAndAbortingTransaction() {
committingTransactions.forEach(k ->View on GitHub (pinned to 820761864e)
Solutions
- Identify the tcId/sequenceId in the message and inspect the corresponding transaction log entry
- Confirm all brokers run a consistent Pulsar version that understands the log's operation codes
- Check the transaction log ledger for corruption; use managed-ledger recovery/repair tooling if entries are damaged
- If corruption is confirmed, move the affected transaction log to a recovery ledger per Pulsar transaction recovery docs and restart
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check: read the transaction log entry's op field and confirm it is one of // COMMITTING, ABORTING, COMMITTED, ABORTED before invoking updateTransactionStatus.
Try / catch
try {
tracker.updateTransactionStatus(tcId, sequenceId, op);
} catch (InvalidTxnStatusException e) {
log.error("Unknown transaction log operation for txn {}:{}", tcId, sequenceId, e);
// stop recovery and escalate for manual ledger inspection
} Prevention
- Avoid version skew between brokers writing and replaying the transaction log
- Verify ledger integrity after unclean shutdowns before recovery
- Never write raw entries into the transaction log with external tooling
- Upgrade all brokers before new transaction log op codes are introduced
When it happens
Trigger: Replaying a transaction log entry whose op/status is not one of COMMITTING, ABORTING, COMMITTED, ABORTED — typically a corrupt entry, a partially-written log record, or an entry written by a newer Pulsar version than the one replaying it.
Common situations: Cluster version skew during rolling upgrade; corrupted transaction log ledger after unclean broker shutdown; manual edits or tooling writing raw entries to the transaction log.
Related errors
- Transaction pending ack replay error with illegal state :
- Invalid txnId key:
- Configuration field 'transactionPendingAckBatchedWriteMaxRec
- Configuration field 'transactionPendingAckBatchedWriteMaxSiz
- No usable leader URL (useTls=<tls>, url=<url>, urlTls=<urlTl
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/a3abfa4a1df79bf2.
Report an issue: GitHub.