aeron-io/aeron · error · ControlProtocolException
UNKNOWN_PUBLICATION
UNKNOWN_PUBLICATION
Error message
unknown publication: ${registrationId} What it means
Thrown by Aeron's DriverConductor when a client asks the driver to remove (or revoke) a publication whose registrationId does not match any active PublicationLink in the driver. The driver tracks every publication by the registrationId returned at addPublication time; a remove command only succeeds for a still-live publication. This is a ControlProtocolException with code UNKNOWN_PUBLICATION delivered back to the requesting client.
Solutions
- Verify you pass the exact registrationId returned by the addPublication future (Publication.registrationId()) and remove each publication at most once
- Track publication lifecycle: ignore UNKNOWN_PUBLICATION on cleanup paths, treating it as 'already gone' rather than a failure
- Check the driver is the same instance the publication was added to (driver was not restarted or clustered away)
- Enable driver event log (aeron.driver.event.log) to confirm when the publication link was removed and by whom
Example fix
// before
try { aeron.removePublication(publication.registrationId()); } catch (ControlProtocolException e) { throw e; }
// after
long regId = publication.registrationId();
try {
aeron.removePublication(regId);
} catch (ControlProtocolException e) {
if (e.errorCode() == ControlProtocolException.Code.UNKNOWN_PUBLICATION) {
// publication already closed/reaped - treat as success on cleanup path
} else { throw e; }
} Defensive patterns
Strategy: try-catch
Validate before calling
if (publication.isClosed()) { return; } // publication already gone, skip removal
final long regId = publication.registrationId(); Type guard
boolean isKnownPublication(Aeron aeron, long registrationId) { return registrationId > 0 && !publication.isClosed(); } Try / catch
try {
aeron.removePublication(regId);
} catch (ControlProtocolException e) {
if (e.errorCode() != ControlProtocolException.Code.UNKNOWN_PUBLICATION) throw e;
// idempotent: publication already removed or reaped
} Prevention
- Always capture the registrationId from the Publication object at add time
- Remove each publication exactly once from a single lifecycle owner
- Treat UNKNOWN_PUBLICATION as success in cleanup/shutdown paths
- Watch driver event log for keepalive-timeout reaping of your publications
When it happens
Trigger: Calling Aeron.removePublication() (or driver control removePublication with revoke=true) with a registrationId that was never added, was already removed, or belonged to a publication closed when its client timed out.
Common situations: Double-removing the same publication; using a stale registrationId after a driver restart or client keepalive timeout reaped the publication; mixing up publication vs counter/subscription registration ids; caching ids across a driver reconnection.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- unknown subscription
- UNKNOWN_COUNTER
- Driver events adapter is invalid
- no response from MediaDriver within
- MediaDriver ( ) keepalive: age= ms > timeout= ms
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/742ff89a82941ad6.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:764
void onRemovePublication(final long registrationId, final long correlationId, final boolean revoke)
{
PublicationLink publicationLink = null;
final ArrayList<PublicationLink> publicationLinks = this.publicationLinks;
for (int i = 0, size = publicationLinks.size(); i < size; i++)
{
final PublicationLink publication = publicationLinks.get(i);
if (registrationId == publication.registrationId())
{
publicationLink = publication;
fastUnorderedRemove(publicationLinks, i);
break;
}
}
if (null == publicationLink)
{
throw new ControlProtocolException(UNKNOWN_PUBLICATION, "unknown publication: " + registrationId);
}
if (revoke)
{
publicationLink.revoke();
}
publicationLink.close();
clientProxy.operationSucceeded(correlationId);
}
void onAddSendDestination(final long registrationId, final String destinationChannel, final long correlationId)
{
scheduleClientCommand(new AddSendDestinationCommand(registrationId, destinationChannel, correlationId));
}
void onRemoveSendDestination(final long registrationId, final String destinationChannel, final long correlationId)
{
scheduleClientCommand(new RemoveSendDestinationCommand(registrationId, destinationChannel, correlationId));View on GitHub (pinned to 6d60124e15)