DEV Community

John Wick
John Wick

Posted on

Fixing "Address Already in Use" When Redeploying a Python Bot

A tutorial for diagnosing and fixing OSError: Address already in use in a python bot deployment — common causes and the actual fixes.

Fixing "Address Already in Use" When Redeploying a Python Bot

OSError: [Errno 98] Address already in use
Enter fullscreen mode Exit fullscreen mode

This error shows up right when you least want it — usually right after a redeploy, right when you're trying to confirm a fix actually worked. Here's what it actually means, the most common causes in a bot deployment specifically, and how to resolve each one.

Table of Contents

  1. What This Error Actually Means
  2. Cause 1: A Previous Process Didn't Fully Exit
  3. Cause 2: Calling a Server-Starting Function Twice
  4. Cause 3: Two Services Configured for the Same Port
  5. Diagnosing Which Cause You Have
  6. Fix: Killing a Leftover Process Locally
  7. Fix: Checking for a Duplicate run() Call
  8. Fix: Platform-Level Port Conflicts
  9. Preventing This Going Forward
  10. FAQs
  11. Conclusion

What This Error Actually Means

At the OS level, only one process can bind to a given (host, port) combination at a time. This error means something is already listening on the port your bot is trying to use — whether that's a leftover process from a previous run, a genuine second server trying to start in the same process, or (less commonly) a platform-level conflict.

Cause 1: A Previous Process Didn't Fully Exit

The most common cause during local development: you stopped your bot with Ctrl+C, but the OS hasn't fully released the port yet, or a child process from a previous run is still alive in the background.

python main.py
# OSError: [Errno 98] Address already in use
Enter fullscreen mode Exit fullscreen mode

Cause 2: Calling a Server-Starting Function Twice

If you're using StayPresent and see this error, it's worth checking whether staypresent.run() is being called more than once in the same process — accidentally, in a script that imports itself, or from two different code paths. As of recent StayPresent versions, this specific case is caught with a clearer RuntimeError explaining the actual issue before it ever reaches the OS-level bind attempt:

staypresent.run("bot.py")
staypresent.run("bot.py")  # RuntimeError: run() already called in this process
Enter fullscreen mode Exit fullscreen mode

If you're seeing the raw OSError instead of that clearer message, you're likely on an older version, or the second "server start" is coming from somewhere other than StayPresent's own run().

Cause 3: Two Services Configured for the Same Port

On a hosting platform, this can happen if two separate deployments (or two processes within one deployment, like a leftover worker from a bad redeploy) are both configured to bind the same port.

Diagnosing Which Cause You Have

Locally, check what's actually using the port:

# macOS/Linux
lsof -i :8080

# Windows
netstat -ano | findstr :8080
Enter fullscreen mode Exit fullscreen mode

If something unexpected shows up, that's your leftover process. If nothing shows up but the error persists, the cause is more likely a duplicate run() call within your own code.

Fix: Killing a Leftover Process Locally

# macOS/Linux — replace <PID> with the process ID from lsof
kill -9 <PID>

# Windows — replace <PID> with the PID from netstat
taskkill /PID <PID> /F
Enter fullscreen mode Exit fullscreen mode

Fix: Checking for a Duplicate run() Call

Search your codebase for every call to staypresent.run() (or any raw app.run()/serve() call, if you're not using StayPresent). A common trigger is an entry-point script being imported by something else, causing top-level code — including a run() call — to execute a second time.

# Guard against accidental double-execution on import
if __name__ == "__main__":
    staypresent.run("bot.py")
Enter fullscreen mode Exit fullscreen mode

Fix: Platform-Level Port Conflicts

If this only happens on your hosting platform and not locally, check for a leftover deployment or process still bound to the same port from a previous, incomplete redeploy. Most platforms fully tear down the old process before starting the new one, but a stuck or hung previous deployment can occasionally linger — a manual restart of the service (not just a redeploy) often clears this.

Preventing This Going Forward

  • Always guard your entry point with if __name__ == "__main__":.
  • Read the port from the environment (os.getenv("PORT", 8080)) rather than hardcoding it, so local testing and deployment don't collide over the same fixed value.
  • If you're on an older StayPresent version and want the clearer duplicate-call error instead of the raw OS error, upgrading is worth it specifically for that improved diagnostic.

FAQs

Does this mean my bot's code is broken?
Not necessarily — it's frequently an environment issue (a leftover process) rather than a logic bug, especially during local development.

Can two bots share the same port?
No — each service needs its own distinct port. If you're running multiple bots, they should share one StayPresent deployment (one port, multiple supervised bot processes) rather than each trying to bind the same port independently.

Why does StayPresent raise RuntimeError instead of letting this OS error happen?
A duplicate run() call is a common, easy mistake, and the raw OSError: Address already in use gives no indication of the actual cause. Catching it earlier with a clearer message saves the debugging time this tutorial is otherwise about.

Conclusion

"Address already in use" almost always traces back to one of three things: a leftover process from a previous run, an accidental duplicate call to whatever starts your server, or a platform-level conflict from an incomplete redeploy. Checking for a lingering process locally, guarding your entry point against double execution, and reading your port from the environment resolves the overwhelming majority of cases.

pip install staypresent[prod]
Enter fullscreen mode Exit fullscreen mode

Top comments (0)