← Back to blog

Guide

Rails says a server is already running: the pid file, and the port

September 14, 20263 min read

Rails gives you two different failures that both look like “the server will not start”, and they need opposite fixes. Reading the message carefully is most of the work.

Failure one: the pid file

A server is already running. Check /your/app/tmp/pids/server.pid.

This message is not about the port. Rails writes its process ID to tmp/pids/server.pid when it starts and removes the file when it stops. If the process dies without cleaning up, a crash, a kill -9, a closed terminal, the file survives with a process ID that no longer exists.

Rails sees the file, assumes a server is running, and refuses before it ever touches port 3000.

Check whether the process is actually alive:

cat tmp/pids/server.pid
ps -p $(cat tmp/pids/server.pid)

If ps prints nothing but a header, the ID is stale and the file is lying. Delete it:

rm tmp/pids/server.pid

Then start normally. If ps does show a live Rails process, it is genuinely running and you want the next section instead.

Failure two: the port really is taken

Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE)

That is the real port conflict, and the pid file has nothing to do with it. Something else holds 3000: another Rails app, a Node dev server, a Docker container publishing 3000.

Find it:

lsof -i :3000

And clear it:

lsof -ti :3000 | xargs kill

If the process is a docker-proxy, do not kill it. Stop the container instead, otherwise Docker will simply put it back.

Why Rails hits the pid file case so often

Two habits make it common.

Ctrl+C is the clean exit, closing the terminal is not. Ctrl+C lets Rails remove the pid file. Closing the window, or quitting the terminal app with the server in the foreground, frequently does not.

kill -9 skips the cleanup by definition. SIGKILL cannot be caught, so the process has no opportunity to delete anything. If you habitually reach for -9, you will habitually leave stale pid files. Use a plain kill first and let it exit properly.

Puma, and multiple workers

If you run Puma in clustered mode, the port is held by several processes at once, the parent and its workers. Killing one worker frees nothing, because the others still hold the port.

This is exactly why the xargs form matters:

lsof -ti :3000 | xargs kill

-t prints every process ID on the port and xargs passes all of them to one kill, so the whole cluster goes together.

Running on another port

Sometimes you just want to get on with it:

rails server -p 3001

Worth doing permanently if you routinely have two Rails apps open. Two projects sharing the framework default is a conflict you have scheduled for yourself.

A quick order of operations

  1. Read the message. Pid file, or EADDRINUSE?
  2. Pid file: check ps, delete the file if the process is gone.
  3. EADDRINUSE: lsof -i :3000, then kill it, or stop the container if it is Docker.
  4. In a hurry: -p 3001.

More on the underlying error in what EADDRINUSE actually means.

Bosun shows what is holding port 3000 in your menu bar, with Docker containers named rather than shown as docker-proxy, and collapses a Puma cluster into a single row. macOS 14 or later, 14 day trial.

See this instead of typing it

Bosun lives in your menu bar and shows every open port on your Mac, live, mapped to the process behind it. One-click kill, SIGTERM first. Useful the first time this happens. Genuinely useful the fifth time it happens in one afternoon.