aeron-io/aeron · error · AeronException
registration id is not a Publication
Error message
registration id is not a Publication: ${resource.getClass().getSimpleName()} What it means
Thrown by Aeron's ClientConductor.removePublication when the supplied registration id maps to a resource that exists but is not a Publication (e.g. a Subscription or Counter). The conductor tracks all client resources by registration id, and this cast-guard prevents releasing the wrong resource type.
Solutions
- Pass the registration id returned by addPublication/addExclusivePublication only.
- Check the resource type at the call site; use removeSubscription or removeCounter for other resources.
- Fix id bookkeeping (name variables by resource type) so ids cannot be confused.
Example fix
// before long id = client.addSubscription(channel, streamId).registrationId(); client.removePublication(id); // AeronException // after long pubId = client.addPublication(channel, streamId).registrationId(); client.removePublication(pubId);
Defensive patterns
Strategy: try-catch
Validate before calling
// track ids with the resource that produced them
if (!(resource instanceof Publication)) throw new IllegalStateException("id is not a publication");
client.removePublication(publication.registrationId()); Type guard
boolean isPublicationRegId(long regId) { return conductorResourceFor(regId) instanceof Publication; } // maintain your own registry map Try / catch
try { client.removePublication(regId); } catch (AeronException e) { log.warn("reg id {} is not a Publication: {}", regId, e.getMessage()); } Prevention
- Store registration ids in typed wrappers per resource kind.
- Always take the id from the same object you are releasing.
- Avoid reusing generic long variables across add/remove calls.
When it happens
Trigger: Calling aeronClient.removePublication(registrationId) with an id that was returned from addSubscription, addCounter, or another non-publication registration.
Common situations: Mixing up registration ids stored in a map/registry; swapping ids after refactoring; reusing a variable holding a subscription id in a release call.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- registration id is not a Subscription
- expected format is ' ' or ' :port', but got
- key length out of bounds
- label length exceeds MAX_LABEL_LENGTH: <label.length()>
- label length out of bounds
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/70fe95c20c148b92.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/ClientConductor.java:695
}
}
void removePublication(final long publicationRegistrationId)
{
clientLock.lock();
try
{
if (NULL_VALUE == publicationRegistrationId || isTerminating || isClosed)
{
return;
}
ensureNotReentrant();
final Object resource = resourceByRegIdMap.get(publicationRegistrationId);
if (null != resource && !(resource instanceof Publication))
{
throw new AeronException("registration id is not a Publication: " +
resource.getClass().getSimpleName());
}
final Publication publication = (Publication)resource;
boolean revokeOnClose = false;
if (null != publication)
{
resourceByRegIdMap.remove(publicationRegistrationId);
publication.internalClose();
releaseLogBuffers(
publication.logBuffers(), publication.originalRegistrationId(), EXPLICIT_CLOSE_LINGER_NS);
revokeOnClose = publication.revokeOnClose;
}
if (asyncCommandIdSet.remove(publicationRegistrationId) || null != publication)
{
asyncCommandIdSet.add(
driverProxy.removePublication(publicationRegistrationId, revokeOnClose));View on GitHub (pinned to 6d60124e15)