ruvnet/ruflo · error

Maximum sessions ( ) reached

Error message

Maximum sessions (${this.config.maxSessions}) reached

What it means

MCPSessionManager caps concurrent sessions at config.maxSessions (merged over DEFAULT_SESSION_CONFIG in the constructor, which also starts a cleanup timer). createSession() throws when sessions.size has reached the cap, bounding per-process memory. Slots are only freed when sessions are removed on disconnect/close or reclaimed by the cleanup timer after timeout. The manager exposes getActiveSessions() and getSessionMetrics() for monitoring.

Solutions

  1. Raise maxSessions in the SessionManager config to match real concurrency (and confirm it in code, not just docs)
  2. Free stuck slots: close stale sessions explicitly, or shorten the timeout config so the cleanup timer reclaims abandoned sessions faster
  3. Fix client-side leaks so every connection disconnects cleanly (finally/close handlers)
  4. If load is legitimate, run more server processes and load-balance instead of raising the cap unboundedly

Example fix

// before
const manager = new MCPSessionManager(); // default cap; throws under load

// after
const manager = new MCPSessionManager({
  maxSessions: 500,
});
// monitor before it saturates:
setInterval(() => console.log(manager.getActiveSessions().length), 30_000);
Defensive patterns

Strategy: validation

Validate before calling

const MAX_SESSIONS = 500; // keep in sync with the manager config
if (manager.getActiveSessions().length >= MAX_SESSIONS) {
  return respond503(); // shed load at the edge instead of letting createSession throw
}
const session = manager.createSession(transportType);

Try / catch

try {
  const session = manager.createSession(transportType);
} catch (e) {
  if (e instanceof Error && /Maximum sessions/.test(e.message)) {
    return respond503WithRetryAfter(30); // capacity: back off, do not crash the handler
  }
  throw e;
}

Prevention

When it happens

Trigger: More clients connecting via http/ws/stdio transports than maxSessions, without disconnecting; leaked sessions where a connection was created but initialize never completed and never closed; load tests spawning many short-lived clients; maxSessions configured below expected concurrency.

Common situations: Default cap too low for production traffic; clients crashing without closing so sessions linger until timeout; test suites sharing one manager with a small cap; forgetting to scale horizontally so a single process absorbs all connections.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/93c7f342601ed189. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/shared/src/mcp/session-manager.ts:81

  private totalClosed = 0;
  private totalExpired = 0;

  constructor(
    private readonly logger: ILogger,
    config: SessionConfig = {}
  ) {
    super();
    this.config = { ...DEFAULT_SESSION_CONFIG, ...config };
    this.startCleanupTimer();
  }

  /**
   * Create a new session
   */
  createSession(transport: TransportType): MCPSession {
    // Check max sessions
    if (this.sessions.size >= this.config.maxSessions) {
      throw new Error(`Maximum sessions (${this.config.maxSessions}) reached`);
    }

    const id = this.generateSessionId();
    const now = new Date();

    const session: MCPSession = {
      id,
      state: 'created',
      transport,
      createdAt: now,
      lastActivityAt: now,
      isInitialized: false,
      isAuthenticated: false,
    };

    this.sessions.set(id, session);
    this.totalCreated++;

View on GitHub (pinned to fa13ee4ad6)