{"record":{"id":"5d01078cc1f87cba","repo":"remix-run/react-router","slug":"no-available-port-found","errorCode":null,"errorMessage":"No available port found","messagePattern":"No available port found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/react-router-serve/cli.ts","lineNumber":80,"sourceCode":"  );\n}\n\nfunction parseNumber(raw?: string) {\n  if (raw === undefined) return undefined;\n  let maybe = Number(raw);\n  if (Number.isNaN(maybe)) return undefined;\n  return maybe;\n}\n\nasync function getAvailablePort(\n  preferredPort: number,\n  host?: string,\n): Promise<number> {\n  let preferredAvailablePort = await checkPort(preferredPort, host);\n  let availablePort = preferredAvailablePort ?? (await checkPort(0, host));\n\n  if (availablePort === undefined) {\n    throw new Error(\"No available port found\");\n  }\n\n  return availablePort;\n}\n\nfunction checkPort(port: number, host?: string): Promise<number | undefined> {\n  return new Promise((resolve, reject) => {\n    let server = net.createServer();\n    let listenOptions = host ? { port, host } : { port };\n\n    server.unref();\n\n    server.once(\"error\", (error: NodeJS.ErrnoException) => {\n      if (error.code === \"EADDRINUSE\" || error.code === \"EACCES\") {\n        resolve(undefined);\n      } else {\n        reject(error);\n      }","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router-serve/cli.ts#L62-L98","documentation":"Thrown by the `react-router-serve` CLI when neither the preferred port nor an OS-assigned port (port 0) can be bound. `checkPort` resolves `undefined` for `EADDRINUSE` or `EACCES`, so both failing means the host has no bindable TCP port to hand back.","triggerScenarios":"Calling `react-router-serve` (or `getAvailablePort`) on a machine where every attempted port returns EADDRINUSE/EACCES, including the ephemeral-range fallback from `checkPort(0)`. Also triggered by an environment where the unprivileged port range is exhausted or where the process lacks permission to bind any port.","commonSituations":"Running inside a hardened container/CI sandbox with a restricted port set; SELinux/AppArmor denying the bind; extremely high fd usage leaving no ephemeral ports; a misconfigured `--port` flag pointing at a privileged port (<1024) as a non-root user combined with an ephemeral-range exhaustion.","solutions":["Free or kill whatever holds the ports (e.g. `lsof -i :PORT`, `pkill node`) and retry.","Pass an explicit free port via the CLI `--port` flag or `PORT` env var.","If in a container, ensure the exposed port range permits unprivileged binds and that the ephemeral range is not exhausted.","Run as a user with bind permission for the requested port, or pick a port >1024."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import net from 'node:net';\nasync function isPortFree(port: number, host?: string): Promise<boolean> {\n  return new Promise((resolve) => {\n    const s = net.createServer();\n    s.once('error', () => resolve(false));\n    s.listen({ port, host }, () => s.close(() => resolve(true)));\n  });\n}\n// before starting the server:\nif (!(await isPortFree(port, host))) {\n  console.error(`Port ${port} is busy, choose another with --port`);\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await run();\n} catch (e) {\n  if (e instanceof Error && e.message === 'No available port found') {\n    console.error('No bindable port: free a port or pass --port');\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Pass an explicit free `--port` in containers/CI.","Don't request privileged ports (<1024) as non-root.","Use orchestration that assigns a host port instead of hardcoding."],"tags":["serve","network","port-binding","cli"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}