aeron-io/aeron · error
AERON_ERROR_CODE_MALFORMED_COMMAND
AERON_ERROR_CODE_MALFORMED_COMMAND
Error message
command={msg_type_id} too short: length={length} What it means
The C media driver's conductor command loop read a command whose record length is shorter than the minimum required for the given msg_type_id (or invalid overall). It sets AERON_ERROR_CODE_MALFORMED_COMMAND, logs 'command=%d too short: length=%llu', and skips the message by continuing the ring-buffer reader.
Solutions
- Restart both driver and clients with matching Aeron versions so record layouts agree.
- Remove stale shared-memory files (/dev/shm/aeron-*) and recreate them via a fresh driver start.
- Fix the producer to always write the full command record before committing the length/commit position.
- Check for compiler struct-packing or ABI differences if embedding the C driver/client in the same process.
Example fix
// before: committing before the payload is fully written atomic_inc(&rb->tail, record_length); // after: write full record, memory barrier, then commit length memcpy(rec->data, cmd, cmd_len); release_fence(); rec->length = (int32_t)record_length;
Defensive patterns
Strategy: try-catch
Validate before calling
size_t min_len = aeron_driver_command_min_length(msg_type_id); if (length < min_len) { fprintf(stderr, "refusing to send command %lld: len %llu < %zu\n", (long long)msg_type_id, length, min_len); abort(); } Type guard
static bool command_record_is_complete(const uint8_t *rec, size_t len, size_t expected) { return len >= expected && rec != NULL; } Try / catch
if (aeron_errcode() == -AERON_ERROR_CODE_MALFORMED_COMMAND) { fprintf(stderr, "malformed command in ring buffer: %s\n", aeron_errmsg()); /* halt writer, recreate buffers */ } else if (aeron_errcode() != 0) { fprintf(stderr, "aeron error: %s\n", aeron_errmsg()); } Prevention
- Always write the complete command record before publishing the length/tail.
- Keep client and driver struct layouts identical (same version, same ABI).
- Recreate shared-memory buffers after a crashed producer instead of reusing them.
- Add checksum/size assertions in custom writers of the command ring buffer.
When it happens
Trigger: A writer advanced the ring buffer with a truncated record (wrote length header without the full payload), a corrupted /dev/shm file, or a client with mismatched struct packing/protocol version sending commands the driver considers too small.
Common situations: Crashed client leaving a partially written command; version mismatch between client and driver struct layouts; manual tooling or memory corruption modifying the shared-memory command buffer.
Related errors
- AERON_ERROR_CODE_UNKNOWN_COMMAND_TYPE_ID
- AeronCluster.Context ingressEndpoints must be null when…
- uses the same id as
- Driver events adapter is invalid
- exceeded session limit, streamId=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/908756b3ffafe47a.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/c/aeron_driver_conductor.c:3214
}
default:
AERON_SET_ERR(-AERON_ERROR_CODE_UNKNOWN_COMMAND_TYPE_ID, "command=%d unknown", msg_type_id);
aeron_driver_conductor_log_error(conductor);
break;
}
if (result < 0)
{
aeron_driver_conductor_on_error(conductor, aeron_errcode(), aeron_errmsg(), correlation_id);
}
return AERON_RB_CONTINUE;
malformed_command:
AERON_SET_ERR(
-AERON_ERROR_CODE_MALFORMED_COMMAND, "command=%d too short: length=%" PRIu64, msg_type_id, (uint64_t)length);
aeron_driver_conductor_log_error(conductor);
return AERON_RB_CONTINUE;
}
void aeron_driver_conductor_on_command_queue(void *clientd, void *item)
{
aeron_command_base_t *cmd = (aeron_command_base_t *)item;
cmd->func(clientd, cmd);
}
void aeron_driver_conductor_on_check_for_blocked_driver_commands(aeron_driver_conductor_t *conductor, int64_t now_ns)
{
int64_t consumer_position = aeron_mpsc_rb_consumer_position(&conductor->to_driver_commands);
if (consumer_position == conductor->last_command_consumer_position &&
aeron_mpsc_rb_producer_position(&conductor->to_driver_commands) > consumer_position)
{
int64_t position_change_deadline_ns = conductor->time_of_last_to_driver_position_change_ns +View on GitHub (pinned to 6d60124e15)