facebook/docusaurus · error · Error

Could not find an open port at ${host}.

Error message

Could not find an open port at ${host}.

What it means

Thrown by `choosePort` when the underlying `detect-port` call (or the interactive prompt) throws — i.e. the host/port combination could not be resolved to a free port. The original error is attached as `cause`. It is a fatal dev-server startup failure, not the normal 'port in use' interactive flow.

Source

Thrown at packages/docusaurus/src/server/getHostPort.ts:88

    if (!isInteractive) {
      logger.error(message);
      return null;
    }
    clearConsole();
    const existingProcess = getProcessForPort(defaultPort);
    const {shouldChangePort} = (await prompts({
      type: 'confirm',
      name: 'shouldChangePort',
      message: logger.yellow(`${logger.bold('[WARNING]')} ${message}${
        existingProcess ? ` Probably:\n  ${existingProcess}` : ''
      }

Would you like to run the app on another port instead?`),
      initial: true,
    })) as {shouldChangePort: boolean};
    return shouldChangePort ? port : null;
  } catch (err) {
    throw new Error(
      logger.interpolate`Could not find an open port at ${host}.`,
      {cause: err},
    );
  }
}

export type HostPortOptions = {
  host?: string;
  port?: string;
};

export async function getHostPort(options: HostPortOptions): Promise<{
  host: string;
  port: number | null;
}> {
  const host = options.host ?? 'localhost';
  const basePort = options.port ? parseInt(options.port, 10) : DEFAULT_PORT;
  const port = await choosePort(host, basePort);

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Specify a different port: `--port 3001` or set `PORT` in env.
  2. Use `--host localhost` or `--host 127.0.0.1` instead of a custom hostname.
  3. In CI, pass `--no-open` and ensure a TTY or pre-allocate a known-free port.
  4. Free the occupied port or kill the stale process before retrying.

Example fix

// before
docusaurus start --host my.custom.host
// after
docusaurus start --host 127.0.0.1 --port 3001
Defensive patterns

Strategy: retry

Validate before calling

import detect from 'detect-port';
async function findFreePort(preferred: number) {
  const port = await detect({port: preferred});
  if (port === preferred) return port;
  return detect({port: 0}); // ask OS for any free port
}

Try / catch

try {
  const {host, port} = await getHostPort({host: '127.0.0.1', port: '3000'});
} catch (e) {
  console.error('Port resolution failed; falling back to ephemeral port');
  // re-run with port: 0
}

Prevention

When it happens

Trigger: The `detect({port, hostname})` promise rejects (e.g. invalid host, network error), or the `prompts` call throws in a non-interactive/CI shell. The catch at getHostPort.ts:87 wraps these into a single 'Could not find an open port at <host>' error.

Common situations: Passing an unresolvable `--host` value; running in a sandboxed CI without TTY where prompts abort; Docker/port-binding conflicts; a host that the OS cannot bind (e.g. a hostname not mapped to a local interface).

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/9443859c8f3470a2. Report an issue: GitHub.