aeron-io/aeron · error · TimeoutException

Archive connect timeout: step= publication= subscription=

Error message

Archive connect timeout: step= publication= subscription=

What it means

During connection establishment the client moves through states (awaiting publication to connect, awaiting the control response subscription image, awaiting responses) with an overall deadline. checkDeadline() compares the deadline against the Aeron context nanoClock and throws a TimeoutException naming the current step plus the publication/subscription channels involved, so you can see exactly which stage stalled.

Solutions

  1. Verify the archive is running and the controlRequestChannel endpoint matches the archive's control channel.
  2. Check network reachability (ping/telnet/firewall) for both control request and response channels from the client host.
  3. Increase ctx.messageTimeoutNs() (the connect deadline derives from it) if the network is slow but functional.
  4. Ensure the response channel endpoint/port is unique per client and not aliased; check archive logs for received control requests.

Example fix

// before
ctx.messageTimeoutNs(TimeUnit.SECONDS.toNanos(1));
AeronArchive archive = AeronArchive.connect(ctx);
// after
ctx.messageTimeoutNs(TimeUnit.SECONDS.toNanos(5));
ctx.controlRequestChannel("aeron:udp?endpoint=archive-host:8010");
ctx.controlResponseChannel("aeron:udp?endpoint=client-host:8020|alias=client");
AeronArchive archive = AeronArchive.connect(ctx);
Defensive patterns

Strategy: retry

Validate before calling

// pre-check reachability of the control endpoint before connect
// e.g. DNS resolve + (for TCP) socket probe; for UDP verify config ports differ and are in range

Try / catch

try { archive = AeronArchive.connect(ctx); } catch (TimeoutException e) { log.error("archive connect stalled: " + e.getMessage()); if (attempts++ < 3) { retryWithBackoff(); } else { throw e; } }

Prevention

When it happens

Trigger: step=PUB_CONNECT when the control request publication never gets a connected image (archive not running/unreachable); step=AWAIT_CONTROL_RESPONSE_SUBSCRIPTION or AWAIT_CONTROL_RESPONSE_CONNECTION when the response subscription never establishes or no reply arrives within the timeout.

Common situations: Archive process down or wrong control endpoint/port; firewall blocking UDP; controlResponseChannel endpoint not routable from the client host; archive up but on a different cluster/version ignoring requests; very short messageTimeoutNs under load.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

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

                case AWAIT_CHALLENGE_RESPONSE:
                    pollForResponse();
                    break;

                case DONE:
                    return aeronArchive;

                default:
                    break;
            }

            return null;
        }

        private void checkDeadline()
        {
            if (deadlineNs - ctx.aeron().context().nanoClock().nanoTime() < 0)
            {
                throw new TimeoutException(
                    "Archive connect timeout: step=" + state +
                    " publication=" +
                    (null != archiveProxy ? archiveProxy.publication() : ctx.controlRequestChannel()) +
                    " subscription=" +
                    (null != controlResponsePoller ? controlResponsePoller.subscription() :
                        ctx.controlResponseChannel()));
            }

            if (Thread.currentThread().isInterrupted())
            {
                throw new AeronException("unexpected interrupt");
            }
        }

        private void awaitSubscription()
        {
            final Aeron aeron = ctx.aeron();
            if (NULL_VALUE == subscriptionRegistrationId)

View on GitHub (pinned to 6d60124e15)