nathanmarz/storm · error · RuntimeException
Non-system tuples should never be sent to __system bolt.
Error message
Non-system tuples should never be sent to __system bolt.
What it means
SystemBolt.execute is unconditional: it never processes tuples and throws immediately for any input. The __system bolt exists only to schedule builtin metrics tasks (via prepare), so receiving a tuple means something upstream is emitting to or anchoring toward the __system stream/component, which is never valid.
Solutions
- Find the upstream component emitting to __system and remove that emission (grep for "__system" in topology code and stream declarations).
- Rename any custom output stream that collides with the reserved __system stream name.
- Remove any grouping/anchoring that targets the __system component; it must not receive user tuples.
- If caused by a library, check its version/issue tracker — user code should never route tuples to the system bolt.
Example fix
// before
OutputCollector.emit("__system", tuple, values); // sends tuple to system bolt
// after
OutputCollector.emit(DEFAULT_STREAM_ID, tuple, values); // emit on your own stream Defensive patterns
Strategy: validation
Validate before calling
// Never emit or group to reserved system streams/components
if ("__system".equals(streamId) || "__system".equals(componentId)) {
throw new IllegalArgumentException("__system is reserved; user code must not send tuples to it");
} Prevention
- Treat stream/component names starting with '__' as reserved by Storm.
- Never anchor or emit tuples toward the __system component.
- Grep your topology code for "__system" and "__tick" misuse before deploying.
- Rely on tick tuples (Config.TOPOLOGY_TICK_TUPLE_FREQ_SECS) instead of the system bolt for periodic work.
When it happens
Trigger: Any bolt or spout emits a tuple to the __system component/stream, or declares __system as an output target, delivering a tuple to SystemBolt.execute.
Common situations: Custom code accidentally names a stream '__system' or declares fields grouping/anchoring toward the system component; misconfigured builtin metrics wiring; copying Storm internals' stream names into user topology code.
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
- Could not instantiate a class listed in config under section
- A single worker should have 1 SystemBolt instance.
- MeanReducer::reduce called with unsupported input type
- No output fields defined for component:stream
- TopologyContext.registerMetric can only be called from…
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/195b09be53eacf86.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/backtype/storm/metric/SystemBolt.java:149
context.registerMetric("memory/heap", new MemoryUsageMetric(new AFn() {
public Object invoke() {
return jvmMemRT.getHeapMemoryUsage();
}
}), bucketSize);
context.registerMetric("memory/nonHeap", new MemoryUsageMetric(new AFn() {
public Object invoke() {
return jvmMemRT.getNonHeapMemoryUsage();
}
}), bucketSize);
for(GarbageCollectorMXBean b : ManagementFactory.getGarbageCollectorMXBeans()) {
context.registerMetric("GC/" + b.getName().replaceAll("\\W", ""), new GarbageCollectorMetric(b), bucketSize);
}
}
@Override
public void execute(Tuple input) {
throw new RuntimeException("Non-system tuples should never be sent to __system bolt.");
}
@Override
public void cleanup() {
}
}
View on GitHub (pinned to cdb116e942)