apache/dolphinscheduler · error · RemoteException

encode msg is null

Error message

encode msg is null

What it means

TransporterEncoder.encode throws a RemoteException when asked to encode a null Transporter message. Netty invoked the encoder with no outbound message, which indicates an internal bug: a null object reached the outbound pipeline.

Source

Thrown at dolphinscheduler-extract/dolphinscheduler-extract-base/src/main/java/org/apache/dolphinscheduler/extract/base/protocal/TransporterEncoder.java:33

 * limitations under the License.
 */

package org.apache.dolphinscheduler.extract.base.protocal;

import org.apache.dolphinscheduler.extract.base.exception.RemoteException;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

@Sharable
public class TransporterEncoder extends MessageToByteEncoder<Transporter> {

    @Override
    protected void encode(ChannelHandlerContext ctx, Transporter transporter, ByteBuf out) {
        if (transporter == null) {
            throw new RemoteException("encode msg is null");
        }
        out.writeByte(Transporter.MAGIC);
        out.writeByte(Transporter.VERSION);

        // write header
        byte[] header = transporter.getHeader().toBytes();
        out.writeInt(header.length);
        out.writeBytes(header);

        // write body
        byte[] body = transporter.getBody();
        out.writeInt(body.length);
        out.writeBytes(body);
    }

}

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Find the caller writing a null to the channel and fix it to never write a null Transporter
  2. Add a null check before ctx.writeAndFlush(msg) in the sending code path
  3. Log the call site producing the null response and fix the handler that should have populated it
  4. Ensure failed RPC invocations produce a valid error Transporter rather than null

Example fix

// before
Transporter transporter = buildResponse(request); // may return null
ctx.writeAndFlush(transporter);
// after
Transporter transporter = buildResponse(request);
if (transporter != null) {
    ctx.writeAndFlush(transporter);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// guard every outbound write
if (msg == null) {
    throw new IllegalStateException("Refusing to write null Transporter to channel " + ctx.channel());
}

Type guard

static boolean isSendable(Transporter t) {
    return t != null && t.getHeader() != null;
}

Try / catch

try {
    ctx.writeAndFlush(transporter);
} catch (RemoteException e) {
    if ("encode msg is null".equals(e.getMessage())) {
        // log the pipeline path that produced a null message; fix the producer
    }
}

Prevention

When it happens

Trigger: A null object is written to the Netty channel (ctx.writeAndFlush(null)) and Netty's MessageToByteEncoder hands it to encode() despite the generic type match.

Common situations: RPC invocation returns/produces a null response object that is written directly to the channel; async callback code writing an uninitialized result; custom code writing to the channel without a null check.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/1550edb9123c358e. Report an issue: GitHub.