aeron-io/aeron · error · ControlProtocolException

GENERIC_ERROR

GENERIC_ERROR

Error message

Invalidation reason must be ${MAX_ERROR_MESSAGE_LENGTH} bytes or less

What it means

Thrown by the driver conductor when processing an image rejection request (onRejectImage) whose reason string exceeds ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH (max bytes an error message can occupy in the control protocol flyweight). The rejection reason travels inside a fixed-size control message buffer, so an oversized reason cannot be encoded and the request is rejected with a ControlProtocolException of code GENERIC_ERROR. This is a caller-side input validation failure, not an internal driver fault.

Solutions

  1. Truncate the reason string to ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH bytes before calling rejectImage
  2. Log the full diagnostics separately and pass a short fixed reason such as "rejected by application policy"
  3. Check reason.length() client-side in a helper wrapper around rejectImage that clips to the limit
  4. Upgrade/downgrade client and driver together so both agree on the message length limit

Example fix

// before
subscription.rejectImage(image.correlationId(), image.position(), "Rejected: " + detailedDiagnostics);
// after
String reason = "Rejected: " + detailedDiagnostics;
if (reason.length() > ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH)
{
    reason = reason.substring(0, ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH);
}
subscription.rejectImage(image.correlationId(), image.position(), reason);
Defensive patterns

Strategy: validation

Validate before calling

if (reason == null || reason.length() > ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH)
{
    reason = reason != null ? reason.substring(0, ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH) : "rejected";
}
subscription.rejectImage(imageCorrelationId, position, reason);

Type guard

static boolean isValidReason(String reason)
{
    return reason != null && reason.length() <= ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH;
}

Try / catch

try
{
    subscription.rejectImage(id, position, reason);
}
catch (ControlProtocolException ex)
{
    log.warn("rejectImage rejected: " + ex.getMessage());
}

Prevention

When it happens

Trigger: Calling Aeron.rejectImage(correlationId, position, reason) (via Aeron client or Subscription#rejectImage) with a reason string longer than ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH bytes; the driver throws before looking up the image.

Common situations: Applications building rejection reasons dynamically by concatenating diagnostics, stack traces, or long URIs; embedding user-supplied text as the reason; missing truncation when adapting legacy logging messages to rejectImage API introduced in newer Aeron versions.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/2593c601d6aef3a4. Report an issue: GitHub.

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:1100

    }

    void onTerminateDriver(final DirectBuffer tokenBuffer, final int tokenOffset, final int tokenLength)
    {
        if (ctx.terminationValidator().allowTermination(ctx.aeronDirectory(), tokenBuffer, tokenOffset, tokenLength))
        {
            ctx.terminationHook().run();
        }
    }

    void onRejectImage(
        final long correlationId,
        final long imageCorrelationId,
        final long position,
        final String reason)
    {
        if (reason.length() > ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH)
        {
            throw new ControlProtocolException(GENERIC_ERROR, "Invalidation reason must be " +
                ErrorFlyweight.MAX_ERROR_MESSAGE_LENGTH + " bytes or less");
        }

        final PublicationImage publicationImage = findPublicationImage(imageCorrelationId);

        if (null == publicationImage)
        {
            final IpcPublication foundPublication = getIpcPublication(imageCorrelationId);

            if (null == foundPublication)
            {
                throw new ControlProtocolException(
                    GENERIC_ERROR, "Unable to resolve image for correlationId=" + imageCorrelationId);
            }

            foundPublication.reject(position, reason, this, cachedNanoClock.nanoTime());
        }
        else

View on GitHub (pinned to 6d60124e15)