nathanmarz/storm · error · UnsupportedOperationException
This state is read-only and does not support updates
Error message
This state is read-only and does not support updates
What it means
ReadOnlyState implements State but its beginCommit always throws UnsupportedOperationException because read-only states (backed by e.g. static data or DRPC queries) cannot participate in transactional writes.
Solutions
- Switch the stream to a writable state implementation (e.g. MemoryMapState, Redis/HBase-backed MapState)
- Remove the persist/aggregate operation from the read-only branch of the topology
- Wrap reads only via stateQuery and perform writes on a separate writable state
Example fix
// before
TridentState state = topology.newStream("s", spout)
.groupBy(fields)
.persistentAggregate(readOnlyStateFactory, new Count(), new Fields("count"));
// after
TridentState state = topology.newStream("s", spout)
.groupBy(fields)
.persistentAggregate(MemoryMapState.Factory(), new Count(), new Fields("count")); Defensive patterns
Strategy: validation
Validate before calling
if (stateFactory instanceof ReadOnlyState || state instanceof ReadOnlyState) {
throw new IllegalArgumentException("Cannot persist to read-only state");
} Type guard
boolean isWritable(State s) { return !(s instanceof ReadOnlyState); } Try / catch
try {
state.beginCommit(txid);
} catch (UnsupportedOperationException e) {
LOG.error("Attempted write to read-only state; fix topology wiring", e);
} Prevention
- Use stateQuery only for read-only states
- Keep read-only and writable state factories in clearly named classes
- Review topology wiring: persistentAggregate/partitionPersist require writable states
When it happens
Trigger: A Trident topology writes (state query/ partitionPersist/ persistentAggregate) to a state factory that returns a ReadOnlyState, causing beginCommit at batch start.
Common situations: Accidentally wiring a topology to a read-only state (e.g. a cached/lookup state) in a stream that aggregates or persists; copy-pasting a read-only state factory into a write path.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot have one group have fixed parallelism of two…
- Combiner state updater should receive a single tuple…
- Current batch (
- Trying to initialize transaction for which there should be…
- Expecting previous txid state to be the previous transaction
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/5ba6e06bfbfa871b.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/storm/trident/state/ReadOnlyState.java:24
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package storm.trident.state;
public class ReadOnlyState implements State {
@Override
public void beginCommit(Long txid) {
throw new UnsupportedOperationException("This state is read-only and does not support updates");
}
@Override
public void commit(Long txid) {
throw new UnsupportedOperationException("This state is read-only and does not support updates");
}
}
View on GitHub (pinned to cdb116e942)