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
- Read the message. Pid file, or
EADDRINUSE? - Pid file: check
ps, delete the file if the process is gone. EADDRINUSE:lsof -i :3000, then kill it, or stop the container if it is Docker.- 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.