redis/redis · critical
aeApiAssociate: event port limit exceeded.
Error message
aeApiAssociate: event port limit exceeded.
What it means
Logged (stderr) at src/ae_evport.c:148 as a diagnostic follow-up when port_associate failed specifically with errno == EAGAIN. On Solaris/illumos event ports, EAGAIN indicates the kernel's per-port association resource limit has been exhausted — there are too many fds concurrently associated with the event port. It is emitted immediately after the generic message in error 12 and, like it, ultimately causes the caller to abort(). The 'counter-intuitive' comment at ae_evport.c:237-242 notes EAGAIN is not retried because the limit is structural.
Source
Thrown at src/ae_evport.c:148
events |= POLLIN;
if (mask & AE_WRITABLE)
events |= POLLOUT;
if (evport_debug)
fprintf(stderr, "%s: port_associate(%d, 0x%x) = ", where, fd, events);
rv = port_associate(portfd, PORT_SOURCE_FD, fd, events,
(void *)(uintptr_t)mask);
err = errno;
if (evport_debug)
fprintf(stderr, "%d (%s)\n", rv, rv == 0 ? "no error" : strerror(err));
if (rv == -1) {
fprintf(stderr, "%s: port_associate: %s\n", where, strerror(err));
if (err == EAGAIN)
fprintf(stderr, "aeApiAssociate: event port limit exceeded.");
}
return rv;
}
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
aeApiState *state = eventLoop->apidata;
int fullmask, pfd;
if (evport_debug)
fprintf(stderr, "aeApiAddEvent: fd %d mask 0x%x\n", fd, mask);
/*
* Since port_associate's "events" argument replaces any existing events, we
* must be sure to include whatever events are already associated when
* we call port_associate() again.
*/
fullmask = mask | eventLoop->events[fd].mask;View on GitHub (pinned to 3acc0c49cf)
Solutions
- Reduce maxclients to a value safely below the kernel's per-port association limit (check with 'prctl -n project.max-port-events' on the running project).
- Raise the illumos resource cap: project.max-port-events (and related port rctls) via projmod / prctl / zone config, then restart Redis.
- Investigate a fd leak — confirmed by 'pfiles <pid>' showing far more open fds than active clients — and fix the unclosed-connection path.
- On a non-illumos target where event ports are not needed, rebuild Redis to select epoll/kqueue instead (the ae backend is chosen at compile time).
- Restart the process to clear the saturated port, then monitor association growth to confirm the cap holds.
Example fix
// before — EAGAIN logged once, callers abort()
if (err == EAGAIN)
fprintf(stderr, "aeApiAssociate: event port limit exceeded.");
// after — back off and lower the active association count before retrying
if (err == EAGAIN) {
serverLog(LL_WARNING,"event port limit exceeded; shedding and retrying");
/* drop stale pending associations, then retry port_associate */
rv = port_associate(portfd, PORT_SOURCE_FD, fd, events,(void*)(uintptr_t)mask);
} Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate the fd count against the event-port association limit before associating.
const PORT_MAX_ASSOCIATIONS = 1024; // conservative; confirm against your evport build
function assertWithinPortLimit(associatedCount, pending) {
if (associatedCount + pending > PORT_MAX_ASSOCIATIONS) {
throw new Error(`event port association limit would be exceeded (${associatedCount}+${pending})`);
}
} Type guard
null
Try / catch
null
Prevention
- Track the count of fds currently associated with the port; reject new associations that would breach the documented limit.
- If you must exceed the limit, shard across multiple event ports rather than relying on a single port.
- On evport backends prefer fewer, long-lived connections (pooling) over churning many short-lived ones.
- Read the platform's port_create/port_associate man page to get the real limit for your kernel before sizing.
When it happens
Trigger: Reached inside aeApiAssociate (ae_evport.c:125) only when port_associate returns -1 AND errno == EAGAIN (line 147). This happens when the number of fds actively associated with state->portfd exceeds the kernel's port association capacity. It can fire from any of the three call sites: aeApiAddEvent, aeApiDelEvent re-association, or the aeApiPoll re-association loop (lines 259-272) that bulk re-associates pending_fds before each port_getn.
Common situations: Setting maxclients higher than the illumos event-port association ceiling, running on a SmartOS/OmniOS zone with a small project.max-port-events rctl, or a fd leak that steadily grows the association count. Often appears after a traffic spike or after clients fail to disconnect cleanly, accumulating stale associations.
Related errors
- %s: port_associate: %s
- aeApiPoll: port_getn, %s
- aeApiPoll: epoll_wait, %s
- aeApiPoll: kevent, %s
- aeApiPoll: select, %s
AI-assisted analysis of redis/redis@3acc0c49cf (2026-08-01).
Data as JSON: /data/errors/2e659a107d2c1645.json.
Report an issue: GitHub.