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

  1. Switch the stream to a writable state implementation (e.g. MemoryMapState, Redis/HBase-backed MapState)
  2. Remove the persist/aggregate operation from the read-only branch of the topology
  3. 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

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


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)