Port Monitor

Port 5000 or 7000 already in use on Mac? It is AirPlay Receiver

Since macOS Monterey, the AirPlay Receiver feature makes Control Center listen on TCP ports 5000 and 7000. Flask, AirPlay-unaware tools and anything else that defaults to port 5000 fails with "address already in use" on a Mac that has never run a server. Turn AirPlay Receiver off, or use another port.

Updated . Applies to macOS.

The symptom

Flask is the usual victim, because its default port is 5000:

$ flask run
Address already in use
Port 5000 is in use by another program. Either identify and stop that program, or start the server with a different port.
On macOS, try disabling the 'AirPlay Receiver' service from System Preferences -> General -> AirDrop & Handoff.

Other servers print their own variant of EADDRINUSE or Errno 48. Port 7000 shows the same thing.

Confirm it is AirPlay

lsof -nP -iTCP:5000 -sTCP:LISTEN
COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ControlCe 612 mikko    7u  IPv4 0x2a4f1c8e9d0b3a21      0t0  TCP *:5000 (LISTEN)
ControlCe 612 mikko    8u  IPv6 0x2a4f1c8e9d0b3a22      0t0  TCP *:5000 (LISTEN)

ControlCe is lsof truncating ControlCenter, the macOS process that also draws the menu bar controls. It listens on both 5000 and 7000 while AirPlay Receiver is on.

Turn AirPlay Receiver off

macOS Ventura and later, including Sonoma, Sequoia and Tahoe: open System Settings, go to General, then AirDrop & Handoff, and switch off AirPlay Receiver.

macOS Monterey: open System Preferences, go to Sharing, and untick AirPlay Receiver.

The ports are released immediately; run the lsof command again to check. The only thing you lose is the ability to stream from an iPhone, iPad or another Mac to this Mac's screen. Everything else about AirPlay, including sending from this Mac to a TV, keeps working.

Do not kill Control Center

kill works on it, and for a few seconds the port is free. Then launchd restarts Control Center, your menu bar flickers, and the port is taken again. Turning the feature off is the only fix that sticks. This is also why the usual kill-the-process recipe does not apply here.

Or move your app

If you would rather keep AirPlay Receiver, run the server on another port. Flask:

flask run -p 5001

The flags for other frameworks are listed in fix EADDRINUSE: address already in use. Whichever you choose, put it in the project's run script so the next person on a Mac does not hit the same wall.

What Port Monitor shows here

Port Monitor excludes Control Center's ports 5000 and 7000 by default, along with a few other macOS services, so its list only contains servers you started. If you turn AirPlay Receiver off and want to keep an eye on 5000 anyway, remove the exclusion in Settings.