{"record":{"id":"19864708de1ddf48","repo":"nathanmarz/storm","slug":"expecting-tx-state-to-be-initialized-in-strict-order-but","errorCode":null,"errorMessage":"Expecting tx state to be initialized in strict order but there are txids after that have state","messagePattern":"Expecting tx state to be initialized in strict order but there are txids after that have state","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"storm-core/src/jvm/backtype/storm/transactional/state/RotatingTransactionalState.java","lineNumber":86,"sourceCode":"    }\n    \n    public Object getState(BigInteger txid, StateInitializer init) {\n        if(!_curr.containsKey(txid)) {\n            SortedMap<BigInteger, Object> prevMap = _curr.headMap(txid);\n            SortedMap<BigInteger, Object> afterMap = _curr.tailMap(txid);            \n            \n            BigInteger prev = null;\n            if(!prevMap.isEmpty()) prev = prevMap.lastKey();\n            \n            if(_strictOrder) {\n                if(prev==null && !txid.equals(TransactionalSpoutCoordinator.INIT_TXID)) {\n                    throw new IllegalStateException(\"Trying to initialize transaction for which there should be a previous state\");\n                }\n                if(prev!=null && !prev.equals(txid.subtract(BigInteger.ONE))) {\n                    throw new IllegalStateException(\"Expecting previous txid state to be the previous transaction\");\n                }\n                if(!afterMap.isEmpty()) {\n                    throw new IllegalStateException(\"Expecting tx state to be initialized in strict order but there are txids after that have state\");                \n                }                \n            }\n            \n            \n            Object data;\n            if(afterMap.isEmpty()) {\n                Object prevData;\n                if(prev!=null) {\n                    prevData = _curr.get(prev);\n                } else {\n                    prevData = null;\n                }\n                data = init.init(txid, prevData);\n            } else {\n                data = null;\n            }\n            _curr.put(txid, data);\n            _state.setData(txPath(txid), data);","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/nathanmarz/storm/blob/cdb116e942666973bc4eaa0df098d5bab82739e7/storm-core/src/jvm/backtype/storm/transactional/state/RotatingTransactionalState.java#L68-L104","documentation":"Strict-order mode also demands that transactions get state in ascending order: if the requested txid has entries that come AFTER it (afterMap not empty, i.e. later txids already have state), the ordering invariant is broken and getState() throws IllegalStateException.","triggerScenarios":"Calling getStateOrCreate(txid) with _strictOrder=true when entries exist in the state store whose txid is greater than the requested txid (initializing an out-of-order / backdated transaction).","commonSituations":"A failed transaction rolled back then re-initialized with a different (lower) txid while later transactions already committed; coordinator restarted and began new transactions while orphaned state from a previous run remains; concurrent or manual cleanup deleting the middle of a txid chain.","solutions":["Remove the newer txid entries (afterMap) or restore the store so txids are initialized in strictly ascending order","Wipe the transactional state and restart the topology from INIT_TXID for a clean rebuild (accepting replay semantics)","Disable strict ordering (_strictOrder=false) if your spout tolerates out-of-order state initialization"],"exampleFix":"// before\nrotatingState.getStateOrCreate(prevTxid); // txids 11,12 already have state\n// after\nfor (BigInteger later : laterTxidsWithState) {\n    rotatingState.removeState(later);\n}\nrotatingState.getStateOrCreate(prevTxid);","handlingStrategy":"validation","validationCode":"if (strictOrder && state.existsTxidGreaterThan(txid)) {\n    LOG.error(\"Out-of-order initialization: later txids already have state for requested txid {}\", txid);\n    return false;\n}","typeGuard":"boolean isInitInOrder(RotatingTransactionalState s, BigInteger txid) {\n    return !s.hasTxidsAfter(txid);\n}","tryCatchPattern":"try {\n    state.getStateOrCreate(txid);\n} catch (IllegalStateException e) {\n    LOG.error(\"Out-of-order tx state init for txid \" + txid, e);\n    resetTransactionalState(); // wipe and start from INIT_TXID\n}","preventionTips":["Process/initialize transactions only in ascending txid order","Fully roll back state of a failed transaction's successors before retrying it with a lower txid","Prefer wiping to a clean state over manual state surgery on txid chains"],"tags":["storm","transactional-spout","txid","state","ordering"],"backgroundTag":"invalid-state-transition","analyzedSha":"cdb116e942666973bc4eaa0df098d5bab82739e7","analyzedAt":"2026-09-12T14:30:00.714Z","contentChangedAt":"2026-09-12T14:30:00.714Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}