redis/node-redis · error · Error

All ports are in use

Error message

All ports are in use

What it means

portIterator is a module-singleton async generator that yields free TCP ports from 6379 to 65534, checking each via isPortAvailable (a connect attempt that returns true on ECONNREFUSED). When the loop exhausts the range with every port occupied, it throws. Note: once the generator throws it becomes closed, so subsequent .next() calls return {done:true, value:undefined} rather than re-throwing — callers then fail later with an undefined-port error.

Source

Thrown at packages/test-utils/lib/dockers.ts:42

    await once(socket, 'connect');
    socket.end();
  } catch (err) {
    if (err instanceof Error && (err as ErrorWithCode).code === 'ECONNREFUSED') {
      return true;
    }
  }

  return false;
}

const portIterator = (async function* (): AsyncIterableIterator<number> {
  for (let i = 6379; i < 65535; i++) {
    if (await isPortAvailable(i)) {
      yield i;
    }
  }

  throw new Error('All ports are in use');
})();

interface RedisServerDockerConfig {
  image: string;
  version: string;
}

interface SentinelConfig {
  mode: "sentinel";
  mounts: Array<string>;
  port: number;
}

interface ServerConfig {
  mode: "server";
}

export type RedisServerDockerOptions = RedisServerDockerConfig & (SentinelConfig | ServerConfig)

View on GitHub (pinned to 90fd0652bc)

Solutions

  1. Remove leaked containers: docker rm -f $(docker ps -aq) or docker ps then remove the redis/test images
  2. Stop other local services occupying ports in the 6379+ range (local redis-server, postgres, etc.)
  3. Reduce parallelism / worker count in the test runner so fewer ports are needed at once

Example fix

# before — ports exhausted, error thrown
# (leaked containers from a prior run)

# after — reclaim ports
docker rm -f $(docker ps -aq --filter 'ancestor=redislabs/client-libs-test')
# rerun the suite
Defensive patterns

Strategy: validation

Validate before calling

import { createConnection } from 'node:net';
async function countFreePorts(from = 6379, to = 65535, sample = 50): Promise<number> {
  let free = 0;
  for (let p = from; p < to && free < sample; p++) {
    try {
      const s = createConnection({ port: p });
      await new Promise((res, rej) => { s.once('connect', () => { s.end(); res(null); }); s.once('error', rej); });
    } catch { free++; }
  }
  return free;
}

Try / catch

try {
  const docker = await spawnRedisServerDocker(opts, args);
} catch (e) {
  if (e instanceof Error && /All ports are in use/.test(e.message)) {
  }
  throw e;
}

Prevention

When it happens

Trigger: Running the test suite with many concurrent Docker containers, or leaving leaked Redis containers bound to host ports (the suite uses --network host), until the entire 6379–65534 range is occupied.

Common situations: A previous test run crashed without cleanup, leaving containers alive; CI runners with low port hygiene; many parallel test workers each consuming ports; another service (local Redis, dev DBs) squatting on the low range.

Related errors


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/e1a703e3375204be. Report an issue: GitHub.