aeron-io/aeron · error · ControlProtocolException
MALFORMED_COMMAND
MALFORMED_COMMAND
Error message
command={msgTypeId} too short: length={length} What it means
Aeron's driver control-protocol flyweights validate that an incoming command message carries at least MINIMUM_LENGTH bytes before fields are decoded. When RemoveMessageFlyweight.validateLength sees a length below that fixed minimum, the command is malformed and a ControlProtocolException with MALFORMED_COMMAND is thrown. This protects the client/driver from reading garbage or out-of-bounds fields from a truncated buffer.
Solutions
- Ensure the command buffer is allocated at least RemoveMessageFlyweight.MINIMUM_LENGTH bytes and that the length passed to the driver matches the encoded message.
- Rebuild client and driver from the same Aeron version so the control-protocol layout matches.
- If assembling commands manually, call validateLength before putting the message on the control queue to catch the bug at the source.
- Verify the term/cnc buffers are not corrupted; restart the driver to recreate them.
Example fix
// before UnsafeBuffer buf = new UnsafeBuffer(new byte[8]); removeMessageFlyweight.setRegistrationId(0, regId); // after UnsafeBuffer buf = new UnsafeBuffer(new byte[RemoveMessageFlyweight.MINIMUM_LENGTH]); removeMessageFlyweight.setRegistrationId(0, regId); removeMessageFlyweight.validateLength(msgTypeId, buf.capacity());
Defensive patterns
Strategy: validation
Validate before calling
if (buffer.capacity() < RemoveMessageFlyweight.MINIMUM_LENGTH) { throw new IllegalArgumentException("buffer too small for remove command"); } Try / catch
try { flyweight.validateLength(msgTypeId, length); driverProxy.removePublication(regId); } catch (ControlProtocolException e) { if (e.errorCode() == ControlProtocolEvents.MALFORMED_COMMAND) { log.error("malformed command", e); } } Prevention
- Always size command buffers from the flyweight's MINIMUM_LENGTH or computeLength
- Keep client and driver on the same Aeron version
- Call validateLength immediately after encoding
- Never hand-edit the command ring buffer
When it happens
Trigger: Sending a remove-registration (RICK/REMOVE) command whose buffer length is below MINIMUM_LENGTH, e.g. a truncated or miswritten publication to the driver's control channel, or passing a wrong length to the flyweight.
Common situations: Buffer under-allocation when assembling commands by hand, protocol version mismatches between client and media driver, corrupted shared-memory (cnc) files, or third-party code writing to the control stream with a wrong length header.
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/5169f4433667d20a.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/command/RemoveMessageFlyweight.java:112
*
* @return length of the message in bytes.
*/
public static int length()
{
return LENGTH + SIZE_OF_LONG;
}
/**
* 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);
}
}
}
View on GitHub (pinned to 6d60124e15)