alibaba/arthas · warning · IllegalArgumentException

zero length message

Error message

zero length message

What it means

TelnetClient.sendSubnegotiation(int[] message) requires at least one byte (the option code) before writing the subnegotiation payload. An empty int[] is rejected with IllegalArgumentException("zero length message") before any I/O. This is the commons-net Telnet option-subnegotiation API used internally by the Arthas telnet client.

Source

Thrown at client/src/main/java/org/apache/commons/net/telnet/TelnetClient.java:223

     * the first byte in {@code message} should be the appropriate telnet
     * option code.
     *
     * <p>
     * This method does not wait for any response. Subnegotiation messages
     * sent by the remote end can be handled by registering an approrpriate
     * {@link TelnetOptionHandler}.
     * </p>
     *
     * @param message option code followed by subnegotiation payload
     * @throws IllegalArgumentException if {@code message} has length zero
     * @throws IOException if an I/O error occurs while writing the message
     * @since 3.0
     ***/
    public void sendSubnegotiation(int[] message)
    throws IOException, IllegalArgumentException
    {
        if (message.length < 1) {
            throw new IllegalArgumentException("zero length message");
        }
        _sendSubnegotiation(message);
    }

    /***
     * Sends a command byte to the remote peer, adding the IAC prefix.
     *
     * <p>
     * This method does not wait for any response. Messages
     * sent by the remote end can be handled by registering an approrpriate
     * {@link TelnetOptionHandler}.
     * </p>
     *
     * @param command the code for the command
     * @throws IOException if an I/O error occurs while writing the message
     * @throws IllegalArgumentException  on error
     * @since 3.0
     ***/

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Guard the call: only invoke sendSubnegotiation when message.length >= 1.
  2. Fix the upstream logic that builds the payload so it always includes the leading option code.
  3. If using an option handler, ensure its subnegotiation callbacks return non-empty arrays (or null/no-op).

Example fix

// before
client.sendSubnegotiation(payload);  // payload may be int[0]

// after
if (payload != null && payload.length > 0) {
    client.sendSubnegotiation(payload);
}
Defensive patterns

Strategy: validation

Validate before calling

if (message != null && message.length > 0) {
    client.sendSubnegotiation(message);
}

Type guard

static boolean hasSubnegotiationPayload(int[] m) {
    return m != null && m.length > 0;
}

Try / catch

try {
    client.sendSubnegotiation(payload);
} catch (IllegalArgumentException e) {
    if (e.getMessage().equals("zero length message")) {
        // nothing to send; no-op
    } else throw e;
}

Prevention

When it happens

Trigger: Calling sendSubnegotiation(new int[0]) or with a list that resolved to zero elements — typically a programmatic caller building an option payload that ended up empty due to a filtering/mapping step returning nothing.

Common situations: Custom TelnetOptionHandler producing an empty subnegotiation array; a code path that sends subnegotiation unconditionally even when there is no payload; defensive/guard code removed by mistake.

Related errors


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/3a4ed9a8bdb73fbe. Report an issue: GitHub.