aeron-io/aeron · error · InvalidChannelException

tag is reserved: channel=

Error message

<INVALID_TAG> tag is reserved: channel=<channelUri>

What it means

Sentinel validation in the driver's entity tag parsing for tagged publications/subscriptions. The tag= URI parameter identifies an entity by long value, and Aeron reserves the special value INVALID_TAG (-1) as the 'no tag' sentinel, so it cannot be used as an actual entity tag. The exception fires when the parsed entityTag equals INVALID_TAG, rejecting a channel URI that explicitly assigns the reserved sentinel value.

Solutions

  1. Choose any tag value other than -1, e.g. a positive session-like id.
  2. If the tag is optional, omit the tag param from the URI instead of using -1.
  3. Add a pre-check: if (tag == Aeron.NULL_VALUE) omit or replace the tag before building the URI.

Example fix

// before
String channel = "aeron:udp?endpoint=localhost:40456|tag=" + tag; // tag == -1
// after
String channel = tag != Aeron.NULL_VALUE
    ? "aeron:udp?endpoint=localhost:40456|tag=" + tag
    : "aeron:udp?endpoint=localhost:40456";
Defensive patterns

Strategy: validation

Validate before calling

if (tag == Aeron.NULL_VALUE) { throw new IllegalArgumentException("tag=-1 is reserved; omit tag or use another value"); }

Prevention

When it happens

Trigger: Adding a publication with |tag=-1 (or any value equal to Aeron.NULL_VALUE / INVALID_TAG) in the channel URI.

Common situations: Using -1 as a default/placeholder tag value in configuration; code that forwards Aeron.NULL_VALUE into the URI; misconfigured tag generators starting at -1.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/PublicationParams.java:610

private static long parseEntityTag(
    final String tagParam, final DriverConductor driverConductor, final ChannelUri channelUri)
{
    final long entityTag;
    try
    {
        entityTag = Long.parseLong(tagParam);
    }
    catch (final NumberFormatException ex)
    {
        throw new InvalidChannelException("invalid entity tag, must be a number", ex);
    }

    if (INVALID_TAG == entityTag)
    {
        throw new InvalidChannelException(INVALID_TAG + " tag is reserved: channel=" + channelUri);
    }

    final NetworkPublication networkPublication = driverConductor.findNetworkPublicationByTag(entityTag);
    if (null != networkPublication)
    {
        throw new InvalidChannelException(entityTag + " entityTag already in use: existingChannel=" +
            networkPublication.channel() + " channel=" + channelUri);
    }

    final IpcPublication ipcPublication = driverConductor.findIpcPublicationByTag(entityTag);
    if (null != ipcPublication)
    {
        throw new InvalidChannelException(entityTag + " entityTag already in use: existingChannel=" +
            ipcPublication.channel() + " channel=" + channelUri);
    }

    return entityTag;
}

View on GitHub (pinned to 6d60124e15)