nathanmarz/storm · error · RuntimeException

null object forbidded in message batch

Error message

null object forbidded in message batch

What it means

MessageBatch.add accumulates TaskMessages and ControlMessages for one network batch. A null element cannot be encoded and would corrupt the batch, so add throws this RuntimeException at MessageBatch.java:42 when obj == null.

Solutions

  1. Null-check each message before adding it to the batch (skip nulls).
  2. Fix the producer/queue so null never enters the message stream; use explicit sentinel objects instead.
  3. In takeMessages/tryAdd wrappers, verify queue poll results before calling add.

Example fix

// before
TaskMessage msg = queue.poll();
batch.add(msg);
// after
TaskMessage msg = queue.poll();
if (msg != null) {
    batch.add(msg);
}
Defensive patterns

Strategy: validation

Validate before calling

if (message == null) return; // skip instead of adding to batch

Type guard

boolean isValidBatchEntry(Object o) {
    return o instanceof TaskMessage || o instanceof ControlMessage;
}

Try / catch

try {
    batch.add(msg);
} catch (RuntimeException e) {
    if (e.getMessage().contains("null object")) {
        LOG.warn("Skipped null message in batch");
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling add(null) directly, or indirectly via tryAdd/takeMessages when a queue/iterator yields null elements (e.g. a poll on an empty buffer misused as a message).

Common situations: Draining a LinkedBlockingQueue with poll()/take() returning null sentinel values that then get added to the batch; custom batching code passing null placeholders; deserialization paths producing null messages.

Related errors


AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12). Data as JSON: /api/errors/77d4f4e6b3347f5f. Report an issue: GitHub.

Appendix: source

Thrown at storm-netty/src/jvm/backtype/storm/messaging/netty/MessageBatch.java:42

import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;

import backtype.storm.messaging.TaskMessage;

class MessageBatch {
    private int buffer_size;
    private ArrayList<Object> msgs;
    private int encoded_length;

    MessageBatch(int buffer_size) {
        this.buffer_size = buffer_size;
        msgs = new ArrayList<Object>();
        encoded_length = ControlMessage.EOB_MESSAGE.encodeLength();
    }

    void add(Object obj) {
        if (obj == null)
            throw new RuntimeException("null object forbidded in message batch");

        if (obj instanceof TaskMessage) {
            TaskMessage msg = (TaskMessage)obj;
            msgs.add(msg);
            encoded_length += msgEncodeLength(msg);
            return;
        }

        if (obj instanceof ControlMessage) {
            ControlMessage msg = (ControlMessage)obj;
            msgs.add(msg);
            encoded_length += msg.encodeLength();
            return;
        }

        throw new RuntimeException("Unsuppoted object type "+obj.getClass().getName());
    }

View on GitHub (pinned to cdb116e942)