nathanmarz/storm · error · IllegalStateException
Trying to initialize transaction for which there should be…
Error message
Trying to initialize transaction for which there should be a previous state
What it means
RotatingTransactionalState.getState() in strict-order mode asserts that a transactional state entry exists only if the requested txid is the very first (INIT_TXID). If no previous txid state exists and the txid is not INIT_TXID, the state store is inconsistent (state was lost or never initialized), so it throws IllegalStateException.
Solutions
- Restore or rebuild the transactional state store so the previous transaction's state exists before this txid
- If the state is genuinely gone and you accept data replay, wipe the coordinator state to restart from INIT_TXID cleanly
- Run with _strictOrder=false (non-strict rotating state) if strict ordering is not required for your spout
Example fix
// before
state.getStateOrCreate(BigInteger.valueOf(nextTxid)); // no prior state stored
// after
if (txid.equals(TransactionalSpoutCoordinator.INIT_TXID) || hasPreviousState(txid)) {
state.getStateOrCreate(txid);
} Defensive patterns
Strategy: validation
Validate before calling
if (strictOrder && txid.compareTo(TransactionalSpoutCoordinator.INIT_TXID) != 0 && state.hasNoPreviousState()) {
LOG.error("Transactional state missing for txid {} ; restore state store before initializing", txid);
return false;
} Type guard
boolean hasRequiredPrevState(RotatingTransactionalState s, BigInteger txid) {
return txid.equals(TransactionalSpoutCoordinator.INIT_TXID) || s.hasPreviousState();
} Try / catch
try {
state.getStateOrCreate(txid);
} catch (IllegalStateException e) {
LOG.error("Transactional state chain broken at txid " + txid, e);
throw new FailedException("State store inconsistent; fail and reinit coordinator", e);
} Prevention
- Never manually delete entries from the transactional state store while the topology runs
- Back up the coordinator state directory/ZK nodes before topology upgrades
- Verify state store contents after crash recovery before restarting a transactional spout
When it happens
Trigger: Calling getStateOrCreate(txid) (which calls getState) with _strictOrder=true when the internal prevMap is empty and txid != TransactionalSpoutCoordinator.INIT_TXID.
Common situations: Corrupted or wiped transactional state in ZooKeeper/Store after disaster recovery; restoring a topology against an old/broken state directory; manually deleting coordinator state; clock/zookeeper metadata loss during failover of a transactional spout.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Expecting previous txid state to be the previous transaction
- Expecting tx state to be initialized in strict order but…
- Failed to get metadata for a transaction
- Cannot have one group have fixed parallelism of two…
- Combiner state updater should receive a single tuple…
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/037da3f38b57c91a.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/backtype/storm/transactional/state/RotatingTransactionalState.java:80
public void removeState(BigInteger txid) {
if(_curr.containsKey(txid)) {
_curr.remove(txid);
_state.delete(txPath(txid));
}
}
public Object getState(BigInteger txid, StateInitializer init) {
if(!_curr.containsKey(txid)) {
SortedMap<BigInteger, Object> prevMap = _curr.headMap(txid);
SortedMap<BigInteger, Object> afterMap = _curr.tailMap(txid);
BigInteger prev = null;
if(!prevMap.isEmpty()) prev = prevMap.lastKey();
if(_strictOrder) {
if(prev==null && !txid.equals(TransactionalSpoutCoordinator.INIT_TXID)) {
throw new IllegalStateException("Trying to initialize transaction for which there should be a previous state");
}
if(prev!=null && !prev.equals(txid.subtract(BigInteger.ONE))) {
throw new IllegalStateException("Expecting previous txid state to be the previous transaction");
}
if(!afterMap.isEmpty()) {
throw new IllegalStateException("Expecting tx state to be initialized in strict order but there are txids after that have state");
}
}
Object data;
if(afterMap.isEmpty()) {
Object prevData;
if(prev!=null) {
prevData = _curr.get(prev);
} else {
prevData = null;
}View on GitHub (pinned to cdb116e942)