aeron-io/aeron · error · ArchiveException

failed to send detach segments request

Error message

failed to send detach segments request

What it means

Thrown when a detachSegments request could not be offered to the archive control publication. ArchiveProxy.detachSegments returned false after retries, so the archive never received the instruction to detach segments at newStartPosition. No storage change occurred; this is a request-delivery failure on the control channel.

Solutions

  1. Reconnect the archive session (AeronArchive.connect) and retry detachSegments.
  2. Verify the archive process and control channel are healthy (logs, error counters) before retrying.
  3. Stagger storage-maintenance operations to avoid control-channel back-pressure.
  4. Reduce session idle time between operations or raise the archive session timeout for maintenance clients.
  5. Confirm the recordingId exists before the call so that a subsequent failure is not confused with a resource problem (this specific error is delivery, not the recording).

Example fix

// before
archive.detachSegments(recordingId, newStartPosition);
// after
try {
    archive.detachSegments(recordingId, newStartPosition);
} catch (ArchiveException e) {
    if (e.message().contains("failed to send")) {
        archive = AeronArchive.connect(ctx);
        archive.detachSegments(recordingId, newStartPosition);
    } else {
        throw e;
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (archive == null || archive.context().isClosed()) { archive = AeronArchive.connect(ctx); }

Type guard

static boolean isSendFailure(ArchiveException e) { return e.getMessage() != null && e.getMessage().contains("failed to send"); }

Try / catch

try { archive.detachSegments(recordingId, newStartPosition); } catch (ArchiveException e) { if (isSendFailure(e)) { archive = AeronArchive.connect(ctx); archive.detachSegments(recordingId, newStartPosition); } else { throw e; } }

Prevention

When it happens

Trigger: Calling AeronArchive.detachSegments(recordingId, newStartPosition) while the control session publication is closed, the archive is unreachable, or the publication is back-pressured beyond the offer retry limit.

Common situations: Storage-management jobs running against an archive that restarted; long-lived housekeeping clients whose sessions timed out; control channel congestion while other archive operations (truncates, purges) run concurrently.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java:2167

     * It is not possible to detach segments which are active for recording or being replayed.
     *
     * @param recordingId      to which the operation applies.
     * @param newStartPosition for the recording after the segments are detached.
     * @see #segmentFileBasePosition(long, long, int, int)
     */
    public void detachSegments(final long recordingId, final long newStartPosition)
    {
        lock.lock();
        try
        {
            ensureConnected();
            ensureNotReentrant();

            lastCorrelationId = aeron.nextCorrelationId();

            if (!archiveProxy.detachSegments(recordingId, newStartPosition, lastCorrelationId, controlSessionId))
            {
                throw new ArchiveException("failed to send detach segments request");
            }

            pollForResponse(lastCorrelationId);
        }
        finally
        {
            lock.unlock();
        }
    }

    /**
     * Delete segments which have been previously detached from a recording.
     *
     * @param recordingId to which the operation applies.
     * @return count of deleted segment files.
     * @see #detachSegments(long, long)
     */
    public long deleteDetachedSegments(final long recordingId)

View on GitHub (pinned to 6d60124e15)