The fastest reliable answer on a modern Linux is one ss command — here's the exact invocation, plus why netstat output misleads people.
Common double-booking: an old instance of the same app, or a second web server squatting on 80/443.
dockerd/docker-proxy binds published ports — ps output shows 'docker-proxy', which confuses netstat readers.
sudo ss -ltnp | grep -E ':443\b'
ps -fp <PID> && ls -l /proc/<PID>/cwd
docker ps --format '{{.Names}} {{.Ports}}' | grep 443
sudo kill <PID> # prefer systemctl stop <unit> when known
Use sudo with ss even as root — without it, process names for other users' sockets are hidden, which is exactly the case when you can't identify the holder. lsof -i :443 is the older equivalent if ss isn't available.
ss -ltnp | grep :<port> (modern) or lsof -i :<port>. ss shows the process name/PID for sockets it owns; run with sudo to see processes owned by other users — the #1 reason people 'can't find' what's on the port.
It's bound to a different interface (127.0.0.1 vs 0.0.0.0 — check ss for the bind address) or a different port (config mismatch). The bind address in ss output is the ground truth the app's config never shows you.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.
One short email when new fixes and production templates drop. No spam, unsubscribe anytime.
Spin up a cloud server in 60 seconds and reproduce this fix yourself — pay by the hour.
Sentry — Free tier: see the exact line of code that broke, before users report it.
We earn a commission if you buy through our links — it never costs you extra. More vetted tools on our picks hub · comparing clouds? DigitalOcean vs Vultr and vs AWS · full deals: DigitalOcean · Vultr · NordLayer · Semrush