reflex-dev/reflex · error · TimeoutError

Backend is not listening.

Error message

Backend is not listening.

What it means

TimeoutError raised by AppHarness._poll_for_servers when the first uvicorn server exists but its `sockets` list is still empty after the polling timeout — the server object was created but never bound/listened on a socket.

Source

Thrown at reflex/testing.py:609

        """
        if self.backend is None:
            msg = "Backend is not running."
            raise RuntimeError(msg)
        backend = self.backend
        # check for servers to be initialized
        if not self._poll_for(
            target=lambda: getattr(backend, "servers", False),
            timeout=timeout,
        ):
            msg = "Backend servers are not initialized."
            raise TimeoutError(msg)
        # check for sockets to be listening
        if not self._poll_for(
            target=lambda: getattr(backend.servers[0], "sockets", False),
            timeout=timeout,
        ):
            msg = "Backend is not listening."
            raise TimeoutError(msg)
        return backend.servers[0].sockets[0]

    def frontend(
        self,
        driver_clz: type[WebDriver] | None = None,
        driver_kwargs: dict[str, Any] | None = None,
        driver_options: ArgOptions | None = None,
        driver_option_args: list[str] | None = None,
        driver_option_capabilities: dict[str, Any] | None = None,
    ) -> WebDriver:
        """Get a selenium webdriver instance pointed at the app.

        Args:
            driver_clz: webdriver.Chrome (default), webdriver.Firefox, webdriver.Safari,
                webdriver.Edge, etc
            driver_kwargs: additional keyword arguments to pass to the webdriver constructor
            driver_options: selenium ArgOptions instance to pass to the webdriver constructor
            driver_option_args: additional arguments for the webdriver options

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Ensure no stale process holds the target port; pass port=0 to let the OS pick a free port
  2. Free stale backend processes between test sessions
  3. Increase resources/reduce parallelism on the CI runner so binding completes in time
Defensive patterns

Strategy: retry

Validate before calling

import socket
with socket.socket() as s:
    s.bind(("127.0.0.1", 0))  # verify binding works; prefer port=0 for the backend

Try / catch

try:
    harness.start()
except TimeoutError as e:
    if "listening" in str(e):
        # likely port conflict; clean up and retry
        harness.start()
    else:
        raise

Prevention

When it happens

Trigger: uvicorn configured on port 0 or a busy port where binding is delayed/failing, or the server's serve() coroutine hasn't run far enough to open sockets within the timeout.

Common situations: Port conflicts from parallel tests or stale processes; firewall/permission issues binding sockets; heavily loaded CI host delaying socket creation.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/34a8b57455d9bcf7. Report an issue: GitHub.