tauri-apps/tauri · error

Couldn't bind to {port} on {ip}

Error message

Couldn't bind to {port} on {ip}

What it means

The built-in dev server (`tauri dev` without a `devUrl`) binds a TCP listener on the given IP. When a port was explicitly requested (`auto_port == false`) and `TcpListener::bind` fails — port already in use, or a privileged/permission-denied port — it aborts. With no explicit port it silently increments from 1430 until a free port is found.

Source

Thrown at crates/tauri-cli/src/dev/builtin_dev_server.rs:46

}

pub fn start<P: AsRef<Path>>(dir: P, ip: IpAddr, port: Option<u16>) -> crate::Result<SocketAddr> {
  let dir = dir.as_ref();
  let dir =
    dunce::canonicalize(dir).fs_context("failed to canonicalize path", dir.to_path_buf())?;

  // bind port and tcp listener
  let auto_port = port.is_none();
  let mut port = port.unwrap_or(1430);
  let (tcp_listener, address) = loop {
    let address = SocketAddr::new(ip, port);
    if let Ok(tcp) = std::net::TcpListener::bind(address) {
      tcp.set_nonblocking(true).unwrap();
      break (tcp, address);
    }

    if !auto_port {
      crate::error::bail!("Couldn't bind to {port} on {ip}");
    }

    port += 1;
  };

  let (tx, _) = channel(1);

  // watch dir for changes
  let tx_c = tx.clone();
  watch(dir.clone(), move || {
    let _ = tx_c.send(());
  });

  let state = ServerState { dir, tx, address };

  // start router thread
  std::thread::spawn(move || {
    tokio::runtime::Builder::new_current_thread()

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Free the port: find the holder with `lsof -i :1430` (macOS/Linux) or `netstat -ano | findstr 1430` (Windows) and kill it
  2. Run with a different port: `tauri dev --port 1431`
  3. Omit the explicit port so the CLI auto-picks the first free port starting at 1430

Example fix

# before
tauri dev --port 1430   # port already in use

# after
kill $(lsof -t -i:1430) 2>/dev/null; tauri dev --port 1430
# or simply: tauri dev   # auto-selects a free port
Defensive patterns

Strategy: validation

Validate before calling

# check the port is free before starting the built-in dev server
PORT=1430
if command -v lsof >/dev/null; then lsof -i :"$PORT" >/dev/null 2>&1 && { echo "port $PORT busy" >&2; exit 1; }
else netstat -ltn 2>/dev/null | grep -q ":$PORT " && { echo "port $PORT busy" >&2; exit 1; }
fi
tauri dev --port $PORT

Prevention

When it happens

Trigger: Starting the built-in dev server with an explicit `--port 1430` while another process (previous dev run, another app, a crashed orphan process) holds that port, or binding a port below 1024 without privileges.

Common situations: Two `tauri dev` instances with a fixed port; a previous dev process that did not exit cleanly; Docker/other services occupying the configured port in CI.

Related errors


AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20). Data as JSON: /api/errors/f8c431c89acd4878. Report an issue: GitHub.