aeron-io/aeron · error · ControlProtocolException
MALFORMED_COMMAND
MALFORMED_COMMAND
Error message
command={msgTypeId} too short: length={length} What it means
The Aeron driver received a control-protocol command message whose total length is below the fixed MINIMUM_LENGTH for a destination (add/remove destination) message. DestinationMessageFlyweight.validateLength() is called by the driver on every incoming command; a too-short buffer means the message header is truncated or the wrong message type was sent, so the driver aborts processing with ControlProtocolException(MALFORMED_COMMAND).
Solutions
- Verify the Aeron client and driver (MediaDriver/SampleConfiguration) use the same Aeron version; upgrade both together.
- Check the code path that writes the destination command buffer to ensure it uses the flyweight's length computation instead of a hard-coded size.
- Enable Aeron logging / driver event log to inspect the raw command that arrived and confirm the length field.
- If writing a custom transport, ensure the full command frame (including channel string length and bytes) is written atomically without truncation.
Example fix
// before buffer.putByte(0, ADD_DESTINATION); buffer.putInt(4, partialLength); // hard-coded, may undershoot MINIMUM_LENGTH // after DestinationMessageFlyweight msg = new DestinationMessageFlyweight(buffer); msg.destination(ADD_DESTINATION, destinationUri, streamId); int length = DestinationMessageFlyweight.computeLength(destinationUri.length()); // publish exactly `length` bytes
Defensive patterns
Strategy: validation
Validate before calling
if (length < DestinationMessageFlyweight.MINIMUM_LENGTH) { throw new IllegalArgumentException("command too short: " + length); } Try / catch
try { flyweight.validateLength(msgTypeId, length); } catch (ControlProtocolException e) { if (e.errorCode() == ControlProtocolException.MALFORMED_COMMAND) { log.error("Malformed control command, dropping", e); } else { throw e; } } Prevention
- Keep Aeron client and driver on identical versions
- Use flyweight APIs instead of manual byte encoding
- Write command frames atomically without truncation
- Check driver event logs when integrating custom command producers
When it happens
Trigger: Sending an ADD_DESTINATION / REMOVE_DESTINATION (or client-side generated) control command whose encoded byte length is less than MINIMUM_LENGTH, e.g. a hand-crafted or corrupted command buffer on the driver control stream, or a client/driver version mismatch producing a shorter message layout.
Common situations: Custom or older Aeron client talking to a newer driver with different message layout; byte-level corruption or truncation of the control command buffer; buggy third-party tooling that fabricates driver control commands; manually multiplexed command streams where a length header is wrong.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/3037792ae6cb3ea0.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/command/DestinationMessageFlyweight.java:155
*
* @return length of the frame in bytes.
*/
public int length()
{
return CHANNEL_OFFSET + lengthOfChannel;
}
/**
* Validate buffer length is long enough for message.
*
* @param msgTypeId type of message.
* @param length of message in bytes to validate.
*/
public void validateLength(final int msgTypeId, final int length)
{
if (length < MINIMUM_LENGTH)
{
throw new ControlProtocolException(
MALFORMED_COMMAND, "command=" + msgTypeId + " too short: length=" + length);
}
if ((length - MINIMUM_LENGTH) < buffer.getInt(offset + CHANNEL_OFFSET))
{
throw new ControlProtocolException(
MALFORMED_COMMAND, "command=" + msgTypeId + " too short for channel: length=" + length);
}
}
/**
* Compute the length of the command message for a given channel length.
*
* @param channelLength to be appended to the header.
* @return the length of the command message for a given channel length.
*/
public static int computeLength(final int channelLength)
{View on GitHub (pinned to 6d60124e15)