aeron-io/aeron · error · IllegalArgumentException

null == channelTag && null != pubSubTag

Error message

null == channelTag && null != pubSubTag

What it means

ChannelUriStringBuilder.tags(Long channelTag, Long pubSubTag) enforces that a pub/sub tag cannot exist without a channel tag, because in the URI encoding the pub-sub tag is only meaningful as the second element of the 'tags' parameter pair. Passing null channelTag with non-null pubSubTag is an invalid combination and throws immediately.

Solutions

  1. Provide both tags: tags(channelTag, pubSubTag) with non-null Long values
  2. If you only have the pub/sub tag, clear both: tags((String)null) or tags(null, null)
  3. Fix the calling logic so channelTag is generated/assigned whenever pubSubTag is set

Example fix

// before
builder.tags(null, 1001L); // throws
// after
builder.tags(1000L, 1001L); // or builder.tags((String)null);
Defensive patterns

Strategy: validation

Validate before calling

if (channelTag == null && pubSubTag != null) throw new IllegalArgumentException("pubSubTag requires a channelTag");

Try / catch

try { builder.tags(channelTag, pubSubTag); } catch (IllegalArgumentException e) { builder.tags((String)null); }

Prevention

When it happens

Trigger: Calling tags(null, 12345L) directly, or code paths where the channel tag is conditionally null but the pub/sub tag is always set.

Common situations: Refactoring where one tag is optional but the other is not; copying tag values from a configuration where only the second tag was populated; building tagged subscriptions with partially-filled tag pairs.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/ChannelUriStringBuilder.java:1254

    {
        return tags(channelUri.get(TAGS_PARAM_NAME));
    }

    /**
     * Set the tags to the specified channel and publication/subscription tag {@link ChannelUri}. The
     * publication/subscription may be null. If channel tag is null, then the pubSubTag must be null.
     *
     * @param channelTag optional value for the channel tag.
     * @param pubSubTag  option value for the publication/subscription tag.
     * @return this for a fluent API.
     * @throws IllegalArgumentException if channelTag is null and pubSubTag is not.
     * @see CommonContext#TAGS_PARAM_NAME
     */
    public ChannelUriStringBuilder tags(final Long channelTag, final Long pubSubTag)
    {
        if (null == channelTag && null != pubSubTag)
        {
            throw new IllegalArgumentException("null == channelTag && null != pubSubTag");
        }

        if (null == channelTag)
        {
            return tags((String)null);
        }

        return tags(channelTag + (null != pubSubTag ? "," + pubSubTag : ""));
    }

    /**
     * Get the tags for a channel used by a publication or subscription. Tags can be used to identify or tag a
     * channel so that a configuration can be referenced and reused.
     *
     * @return the tags for a channel, publication or subscription.
     * @see CommonContext#TAGS_PARAM_NAME
     * @see CommonContext#TAG_PREFIX
     */

View on GitHub (pinned to 6d60124e15)