aeron-io/aeron · error · ArchiveException
failed to send truncate recording request
Error message
failed to send truncate recording request
What it means
AeronArchive.truncateRecording() throws this ArchiveException when the truncate-recording request could not be offered to the archive control-request publication. archiveProxy.truncateRecording() returned false, meaning the message was not enqueued (publication not connected, closed, or back-pressured for the entire retry window), so pollForResponse never runs and the recording is not truncated.
Solutions
- Check that the archive is up and control-channel configuration matches on client and archive.
- Retry truncateRecording after a short backoff; transient back-pressure frequently clears.
- Reconnect with AeronArchive.connect() if the control session has been closed server-side.
- Ensure the recording is stopped and the position is a valid stop position before retrying, so repeated failed offers do not keep filling the buffer.
- Inspect archive logs for session timeouts or publication errors preceding this failure.
Example fix
// before
archive.truncateRecording(recordingId, position);
// after
try {
archive.truncateRecording(recordingId, position);
} catch (ArchiveException e) {
if (e.getMessage().contains("failed to send truncate recording request")) {
// archive unreachable or control session dead; reconnect and retry
try (AeronArchive fresh = AeronArchive.connect(ctx)) {
fresh.truncateRecording(recordingId, position);
}
} else {
throw e;
}
} Defensive patterns
Strategy: retry
Validate before calling
// ensure the recording is stopped and control channel is connected before truncating
if (!archive.archiveProxy().controlPublication().isConnected()) {
throw new IllegalStateException("archive control publication not connected");
}
long stopPos = archive.getStopPosition(recordingId);
if (position < 0 || position > stopPos) {
throw new IllegalArgumentException("truncate position out of range: " + position);
} Try / catch
try {
archive.truncateRecording(recordingId, position);
} catch (ArchiveException e) {
if (e.getMessage().contains("failed to send truncate recording request")) {
Thread.sleep(backoffMs); // reconnect if the session is dead, then retry
} else { throw e; }
} Prevention
- Stop the recording and validate the truncate position before issuing the request.
- Check control-publication connectivity before destructive operations.
- Retry with backoff and reconnect on session loss.
- Avoid chaining truncate right after failed requests that may have saturated the control stream.
When it happens
Trigger: Calling truncateRecording(recordingId, position) when the archive control stream cannot accept the request: archive process down, control session expired or closed by the archive, control-request terminal buffer full, or misconfigured control channel.
Common situations: Rewinding a recording to re-consume it while the archive is restarting; long-lived clients whose session was reaped; truncation issued right after a failed replay request that already saturated the control stream.
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
- failed to send list recordings request
- failed to send list recording request
- failed to send get start position request
- failed to send get recording position request
- failed to send get stop position request
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/6f3b2dcab518bec6.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java:1691
* Truncating a recording will stop any concurrent replays of that recording.
*
* @param recordingId of the stopped recording to be truncated.
* @param position to which the recording will be truncated.
* @return count of deleted segment files.
*/
public long truncateRecording(final long recordingId, final long position)
{
lock.lock();
try
{
ensureConnected();
ensureNotReentrant();
lastCorrelationId = aeron.nextCorrelationId();
if (!archiveProxy.truncateRecording(recordingId, position, lastCorrelationId, controlSessionId))
{
throw new ArchiveException("failed to send truncate recording request");
}
return pollForResponse(lastCorrelationId);
}
finally
{
lock.unlock();
}
}
/**
* Purge a stopped recording, i.e. mark recording as {@link io.aeron.archive.codecs.RecordingState#INVALID}
* and delete the corresponding segment files. The space in the Catalog will be reclaimed upon compaction.
*
* @param recordingId of the stopped recording to be purged.
* @return count of deleted segment files.
*/View on GitHub (pinned to 6d60124e15)