[{"data":1,"prerenderedAt":860},["ShallowReactive",2],{"content-query-cQLyGfP2yU":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"crumb":11,"summary":12,"group":13,"order":14,"port":15,"updated":16,"cta":17,"related":25,"faq":44,"body":57,"_type":853,"_id":854,"_source":855,"_file":856,"_stem":857,"_extension":858,"sitemap":859},"/localhost/5000","localhost",false,"","localhost:5000: Flask port, macOS AirPlay conflict and fixes","localhost:5000 is Flask's default port, but on macOS AirPlay Receiver also uses port 5000. Fix 403 and 'address already in use', and share 5000 publicly.","reference","localhost:5000","Flask, ASP.NET Core (Kestrel fallback), Docker Registry, macOS AirPlay.","Web frameworks",5,5000,"2026-10-28",{"eyebrow":18,"title":19,"text":20,"to":21,"label":22,"secondaryTo":23,"secondaryLabel":24},"Webhook Relay","Receive webhooks on your local Flask app","relay forward gives your Flask app a permanent public webhook URL and delivers each request to localhost:5000 (or 5001, if AirPlay won). Every webhook is logged so you can replay it after a fix. To share the whole app, relay connect gives the port a stable HTTPS URL.","/docs/webhooks/internal/localhost/","Receive webhooks locally","/blog/receiving-shopify-webhooks-flask-api/","Shopify webhooks on Flask",[26,29,32,35,38,41],{"title":27,"to":28},"localhost:8000 (Django, FastAPI)","/localhost/8000/",{"title":30,"to":31},"localhost:3000","/localhost/3000/",{"title":33,"to":34},"localhost:8080","/localhost/8080/",{"title":36,"to":37},"127.0.0.1 and the loopback address","/localhost/127-0-0-1/",{"title":39,"to":40},"401 vs 403","/http-errors/401-vs-403/",{"title":42,"to":43},"What is a webhook listener?","/glossary/webhook-listener/",[45,48,51,54],{"q":46,"a":47},"What is localhost:5000?","localhost:5000 is port 5000 on your own machine. It is the default port of Flask's development server, the fallback address of ASP.NET Core's Kestrel server when no URL is configured, and the default port of the Docker Registry image. On macOS it is also used by the AirPlay Receiver.",{"q":49,"a":50},"Why does localhost:5000 return 403 Forbidden on my Mac?","Since macOS Monterey, the AirPlay Receiver feature listens on ports 5000 and 7000. Your browser is talking to AirPlay, not your Flask app, and it answers with 403. Turn off AirPlay Receiver in System Settings under General, AirDrop and Handoff, or run Flask on another port such as 5001.",{"q":52,"a":53},"How do I change the Flask port?","Run flask run --port 5001, or call app.run(port=5001) if you start the app with python app.py. You can also set the FLASK_RUN_PORT environment variable.",{"q":55,"a":56},"How do I make Flask accessible from other devices?","Start it with flask run --host 0.0.0.0 so it listens on all interfaces, then open http://YOUR-LAN-IP:5000 from a device on the same network. Never use the Flask development server with debug mode on a network you don't trust.",{"type":58,"children":59,"toc":845},"root",[60,104,111,251,284,290,302,353,365,403,409,504,510,598,631,658,664,694,715,721,733,768,795,800,834,839],{"type":61,"tag":62,"props":63,"children":64},"element","p",{},[65,78,80,86,88,94,96,102],{"type":61,"tag":66,"props":67,"children":68},"strong",{},[69,76],{"type":61,"tag":70,"props":71,"children":73},"code",{"className":72},[],[74],{"type":75,"value":11},"text",{"type":75,"value":77}," is the default port of Flask's development server, and on a Mac it's also where the AirPlay Receiver listens.",{"type":75,"value":79}," That overlap is the most common reason ",{"type":61,"tag":70,"props":81,"children":83},{"className":82},[],[84],{"type":75,"value":85},"http://localhost:5000",{"type":75,"value":87}," shows a blank ",{"type":61,"tag":89,"props":90,"children":91},"em",{},[92],{"type":75,"value":93},"403 Forbidden",{"type":75,"value":95}," or Flask fails with ",{"type":61,"tag":70,"props":97,"children":99},{"className":98},[],[100],{"type":75,"value":101},"Address already in use",{"type":75,"value":103}," even though nothing of yours is running. ASP.NET Core's Kestrel (when no URL is configured) and the Docker Registry image also default to 5000.",{"type":61,"tag":105,"props":106,"children":108},"h2",{"id":107},"what-runs-on-port-5000",[109],{"type":75,"value":110},"What runs on port 5000",{"type":61,"tag":112,"props":113,"children":114},"table",{},[115,139],{"type":61,"tag":116,"props":117,"children":118},"thead",{},[119],{"type":61,"tag":120,"props":121,"children":122},"tr",{},[123,129,134],{"type":61,"tag":124,"props":125,"children":126},"th",{},[127],{"type":75,"value":128},"Tool",{"type":61,"tag":124,"props":130,"children":131},{},[132],{"type":75,"value":133},"Default on 5000?",{"type":61,"tag":124,"props":135,"children":136},{},[137],{"type":75,"value":138},"Start command",{"type":61,"tag":140,"props":141,"children":142},"tbody",{},[143,182,208,230],{"type":61,"tag":120,"props":144,"children":145},{},[146,152,157],{"type":61,"tag":147,"props":148,"children":149},"td",{},[150],{"type":75,"value":151},"Flask",{"type":61,"tag":147,"props":153,"children":154},{},[155],{"type":75,"value":156},"Yes",{"type":61,"tag":147,"props":158,"children":159},{},[160,166,168,174,176],{"type":61,"tag":70,"props":161,"children":163},{"className":162},[],[164],{"type":75,"value":165},"flask run",{"type":75,"value":167}," or ",{"type":61,"tag":70,"props":169,"children":171},{"className":170},[],[172],{"type":75,"value":173},"python app.py",{"type":75,"value":175}," with ",{"type":61,"tag":70,"props":177,"children":179},{"className":178},[],[180],{"type":75,"value":181},"app.run()",{"type":61,"tag":120,"props":183,"children":184},{},[185,198,203],{"type":61,"tag":147,"props":186,"children":187},{},[188,190,196],{"type":75,"value":189},"macOS AirPlay Receiver (",{"type":61,"tag":70,"props":191,"children":193},{"className":192},[],[194],{"type":75,"value":195},"ControlCenter",{"type":75,"value":197},")",{"type":61,"tag":147,"props":199,"children":200},{},[201],{"type":75,"value":202},"Yes, since Monterey",{"type":61,"tag":147,"props":204,"children":205},{},[206],{"type":75,"value":207},"On by default",{"type":61,"tag":120,"props":209,"children":210},{},[211,216,221],{"type":61,"tag":147,"props":212,"children":213},{},[214],{"type":75,"value":215},"ASP.NET Core (Kestrel)",{"type":61,"tag":147,"props":217,"children":218},{},[219],{"type":75,"value":220},"Fallback when no URL is set",{"type":61,"tag":147,"props":222,"children":223},{},[224],{"type":61,"tag":70,"props":225,"children":227},{"className":226},[],[228],{"type":75,"value":229},"dotnet run",{"type":61,"tag":120,"props":231,"children":232},{},[233,238,242],{"type":61,"tag":147,"props":234,"children":235},{},[236],{"type":75,"value":237},"Docker Registry",{"type":61,"tag":147,"props":239,"children":240},{},[241],{"type":75,"value":156},{"type":61,"tag":147,"props":243,"children":244},{},[245],{"type":61,"tag":70,"props":246,"children":248},{"className":247},[],[249],{"type":75,"value":250},"docker run -p 5000:5000 registry:2",{"type":61,"tag":62,"props":252,"children":253},{},[254,256,262,264,270,272,282],{"type":75,"value":255},"Newer ",{"type":61,"tag":70,"props":257,"children":259},{"className":258},[],[260],{"type":75,"value":261},"dotnet new",{"type":75,"value":263}," templates set their own ports in ",{"type":61,"tag":70,"props":265,"children":267},{"className":266},[],[268],{"type":75,"value":269},"launchSettings.json",{"type":75,"value":271},", so check that file before assuming 5000. Django and FastAPI use ",{"type":61,"tag":273,"props":274,"children":275},"a",{"href":28},[276],{"type":61,"tag":70,"props":277,"children":279},{"className":278},[],[280],{"type":75,"value":281},"localhost:8000",{"type":75,"value":283},".",{"type":61,"tag":105,"props":285,"children":287},{"id":286},"the-macos-airplay-receiver-conflict",[288],{"type":75,"value":289},"The macOS AirPlay Receiver conflict",{"type":61,"tag":62,"props":291,"children":292},{},[293,295,300],{"type":75,"value":294},"Since macOS 12 Monterey, the AirPlay Receiver listens on ports ",{"type":61,"tag":66,"props":296,"children":297},{},[298],{"type":75,"value":299},"5000 and 7000",{"type":75,"value":301},". Symptoms:",{"type":61,"tag":303,"props":304,"children":305},"ul",{},[306,318,336],{"type":61,"tag":307,"props":308,"children":309},"li",{},[310,312],{"type":75,"value":311},"Flask prints ",{"type":61,"tag":70,"props":313,"children":315},{"className":314},[],[316],{"type":75,"value":317},"Address already in use. Port 5000 is in use by another program.",{"type":61,"tag":307,"props":319,"children":320},{},[321,326,328,334],{"type":61,"tag":70,"props":322,"children":324},{"className":323},[],[325],{"type":75,"value":85},{"type":75,"value":327}," returns 403 with a ",{"type":61,"tag":70,"props":329,"children":331},{"className":330},[],[332],{"type":75,"value":333},"Server: AirTunes",{"type":75,"value":335}," header, even with Flask stopped.",{"type":61,"tag":307,"props":337,"children":338},{},[339,345,347,352],{"type":61,"tag":70,"props":340,"children":342},{"className":341},[],[343],{"type":75,"value":344},"lsof -i :5000",{"type":75,"value":346}," shows ",{"type":61,"tag":70,"props":348,"children":350},{"className":349},[],[351],{"type":75,"value":195},{"type":75,"value":283},{"type":61,"tag":62,"props":354,"children":355},{},[356,358,363],{"type":75,"value":357},"You can't kill ",{"type":61,"tag":70,"props":359,"children":361},{"className":360},[],[362],{"type":75,"value":195},{"type":75,"value":364},"; it comes straight back. Pick one fix:",{"type":61,"tag":366,"props":367,"children":368},"ol",{},[369,385],{"type":61,"tag":307,"props":370,"children":371},{},[372,377,379,384],{"type":61,"tag":66,"props":373,"children":374},{},[375],{"type":75,"value":376},"Turn AirPlay Receiver off:",{"type":75,"value":378}," System Settings, then General, then AirDrop & Handoff, then switch off ",{"type":61,"tag":89,"props":380,"children":381},{},[382],{"type":75,"value":383},"AirPlay Receiver",{"type":75,"value":283},{"type":61,"tag":307,"props":386,"children":387},{},[388,393,395,401],{"type":61,"tag":66,"props":389,"children":390},{},[391],{"type":75,"value":392},"Move Flask:",{"type":75,"value":394}," ",{"type":61,"tag":70,"props":396,"children":398},{"className":397},[],[399],{"type":75,"value":400},"flask run --port 5001",{"type":75,"value":402},". This is the simplest choice for a team, because it doesn't depend on everyone's Mac settings.",{"type":61,"tag":105,"props":404,"children":406},{"id":405},"fix-localhost5000-refused-to-connect",[407],{"type":75,"value":408},"Fix \"localhost:5000 refused to connect\"",{"type":61,"tag":366,"props":410,"children":411},{},[412,452,470],{"type":61,"tag":307,"props":413,"children":414},{},[415,420,422,428,430,435,437,443,445,451],{"type":61,"tag":66,"props":416,"children":417},{},[418],{"type":75,"value":419},"Check Flask is running.",{"type":75,"value":421}," It prints ",{"type":61,"tag":70,"props":423,"children":425},{"className":424},[],[426],{"type":75,"value":427},"Running on http://127.0.0.1:5000",{"type":75,"value":429},". If ",{"type":61,"tag":70,"props":431,"children":433},{"className":432},[],[434],{"type":75,"value":165},{"type":75,"value":436}," can't find the app, set ",{"type":61,"tag":70,"props":438,"children":440},{"className":439},[],[441],{"type":75,"value":442},"FLASK_APP",{"type":75,"value":444}," or use ",{"type":61,"tag":70,"props":446,"children":448},{"className":447},[],[449],{"type":75,"value":450},"flask --app app run",{"type":75,"value":283},{"type":61,"tag":307,"props":453,"children":454},{},[455,460,462,468],{"type":61,"tag":66,"props":456,"children":457},{},[458],{"type":75,"value":459},"Use the URL Flask printed.",{"type":75,"value":461}," Flask binds to ",{"type":61,"tag":70,"props":463,"children":465},{"className":464},[],[466],{"type":75,"value":467},"127.0.0.1",{"type":75,"value":469}," by default. If you started it on another port to dodge AirPlay, open that port.",{"type":61,"tag":307,"props":471,"children":472},{},[473,478,480,486,488,494,496,502],{"type":61,"tag":66,"props":474,"children":475},{},[476],{"type":75,"value":477},"Docker.",{"type":75,"value":479}," Inside a container Flask must run with ",{"type":61,"tag":70,"props":481,"children":483},{"className":482},[],[484],{"type":75,"value":485},"--host 0.0.0.0",{"type":75,"value":487},", and the port needs ",{"type":61,"tag":70,"props":489,"children":491},{"className":490},[],[492],{"type":75,"value":493},"-p 5000:5000",{"type":75,"value":495},". On a Mac, prefer ",{"type":61,"tag":70,"props":497,"children":499},{"className":498},[],[500],{"type":75,"value":501},"-p 5001:5000",{"type":75,"value":503}," so AirPlay doesn't get in the way on the host side.",{"type":61,"tag":105,"props":505,"children":507},{"id":506},"find-and-free-a-busy-port-5000",[508],{"type":75,"value":509},"Find and free a busy port 5000",{"type":61,"tag":511,"props":512,"children":516},"pre",{"className":513,"code":514,"language":515,"meta":7,"style":7},"language-bash shiki shiki-themes github-dark","# macOS / Linux: who owns 5000?\nlsof -i :5000\nkill -9 $(lsof -ti :5000)   # won't help if it's ControlCenter\n","bash",[517],{"type":61,"tag":70,"props":518,"children":519},{"__ignoreMap":7},[520,532,554],{"type":61,"tag":521,"props":522,"children":525},"span",{"class":523,"line":524},"line",1,[526],{"type":61,"tag":521,"props":527,"children":529},{"style":528},"--shiki-default:#6A737D",[530],{"type":75,"value":531},"# macOS / Linux: who owns 5000?\n",{"type":61,"tag":521,"props":533,"children":535},{"class":523,"line":534},2,[536,542,548],{"type":61,"tag":521,"props":537,"children":539},{"style":538},"--shiki-default:#B392F0",[540],{"type":75,"value":541},"lsof",{"type":61,"tag":521,"props":543,"children":545},{"style":544},"--shiki-default:#79B8FF",[546],{"type":75,"value":547}," -i",{"type":61,"tag":521,"props":549,"children":551},{"style":550},"--shiki-default:#9ECBFF",[552],{"type":75,"value":553}," :5000\n",{"type":61,"tag":521,"props":555,"children":557},{"class":523,"line":556},3,[558,563,568,574,578,583,588,593],{"type":61,"tag":521,"props":559,"children":560},{"style":544},[561],{"type":75,"value":562},"kill",{"type":61,"tag":521,"props":564,"children":565},{"style":544},[566],{"type":75,"value":567}," -9",{"type":61,"tag":521,"props":569,"children":571},{"style":570},"--shiki-default:#E1E4E8",[572],{"type":75,"value":573}," $(",{"type":61,"tag":521,"props":575,"children":576},{"style":538},[577],{"type":75,"value":541},{"type":61,"tag":521,"props":579,"children":580},{"style":544},[581],{"type":75,"value":582}," -ti",{"type":61,"tag":521,"props":584,"children":585},{"style":550},[586],{"type":75,"value":587}," :5000",{"type":61,"tag":521,"props":589,"children":590},{"style":570},[591],{"type":75,"value":592},")   ",{"type":61,"tag":521,"props":594,"children":595},{"style":528},[596],{"type":75,"value":597},"# won't help if it's ControlCenter\n",{"type":61,"tag":511,"props":599,"children":603},{"className":600,"code":601,"language":602,"meta":7,"style":7},"language-powershell shiki shiki-themes github-dark","# Windows\nnetstat -ano | findstr :5000\ntaskkill /PID \u003Cpid> /F\n","powershell",[604],{"type":61,"tag":70,"props":605,"children":606},{"__ignoreMap":7},[607,615,623],{"type":61,"tag":521,"props":608,"children":609},{"class":523,"line":524},[610],{"type":61,"tag":521,"props":611,"children":612},{},[613],{"type":75,"value":614},"# Windows\n",{"type":61,"tag":521,"props":616,"children":617},{"class":523,"line":534},[618],{"type":61,"tag":521,"props":619,"children":620},{},[621],{"type":75,"value":622},"netstat -ano | findstr :5000\n",{"type":61,"tag":521,"props":624,"children":625},{"class":523,"line":556},[626],{"type":61,"tag":521,"props":627,"children":628},{},[629],{"type":75,"value":630},"taskkill /PID \u003Cpid> /F\n",{"type":61,"tag":62,"props":632,"children":633},{},[634,636,641,643,649,651,657],{"type":75,"value":635},"Change the Flask port with ",{"type":61,"tag":70,"props":637,"children":639},{"className":638},[],[640],{"type":75,"value":400},{"type":75,"value":642},", ",{"type":61,"tag":70,"props":644,"children":646},{"className":645},[],[647],{"type":75,"value":648},"FLASK_RUN_PORT=5001",{"type":75,"value":650},", or ",{"type":61,"tag":70,"props":652,"children":654},{"className":653},[],[655],{"type":75,"value":656},"app.run(port=5001)",{"type":75,"value":283},{"type":61,"tag":105,"props":659,"children":661},{"id":660},"open-localhost5000-from-another-device",[662],{"type":75,"value":663},"Open localhost:5000 from another device",{"type":61,"tag":511,"props":665,"children":667},{"className":513,"code":666,"language":515,"meta":7,"style":7},"flask run --host 0.0.0.0\n",[668],{"type":61,"tag":70,"props":669,"children":670},{"__ignoreMap":7},[671],{"type":61,"tag":521,"props":672,"children":673},{"class":523,"line":524},[674,679,684,689],{"type":61,"tag":521,"props":675,"children":676},{"style":538},[677],{"type":75,"value":678},"flask",{"type":61,"tag":521,"props":680,"children":681},{"style":550},[682],{"type":75,"value":683}," run",{"type":61,"tag":521,"props":685,"children":686},{"style":544},[687],{"type":75,"value":688}," --host",{"type":61,"tag":521,"props":690,"children":691},{"style":544},[692],{"type":75,"value":693}," 0.0.0.0\n",{"type":61,"tag":62,"props":695,"children":696},{},[697,699,705,707,713],{"type":75,"value":698},"Then open ",{"type":61,"tag":70,"props":700,"children":702},{"className":701},[],[703],{"type":75,"value":704},"http://YOUR-LAN-IP:5000",{"type":75,"value":706}," on a device on the same Wi-Fi. Don't do this with ",{"type":61,"tag":70,"props":708,"children":710},{"className":709},[],[711],{"type":75,"value":712},"--debug",{"type":75,"value":714}," on an untrusted network: the Werkzeug debugger lets anyone who can trigger an error run Python on your machine, protected only by a PIN.",{"type":61,"tag":105,"props":716,"children":718},{"id":717},"receive-webhooks-on-localhost5000",[719],{"type":75,"value":720},"Receive webhooks on localhost:5000",{"type":61,"tag":62,"props":722,"children":723},{},[724,726,731],{"type":75,"value":725},"Flask is a common choice for a quick webhook receiver, but Stripe, Shopify or GitHub can't post to ",{"type":61,"tag":70,"props":727,"children":729},{"className":728},[],[730],{"type":75,"value":5},{"type":75,"value":732},". Forward them to your route:",{"type":61,"tag":511,"props":734,"children":736},{"className":513,"code":735,"language":515,"meta":7,"style":7},"relay forward --bucket flask-hooks http://localhost:5000/webhooks\n",[737],{"type":61,"tag":70,"props":738,"children":739},{"__ignoreMap":7},[740],{"type":61,"tag":521,"props":741,"children":742},{"class":523,"line":524},[743,748,753,758,763],{"type":61,"tag":521,"props":744,"children":745},{"style":538},[746],{"type":75,"value":747},"relay",{"type":61,"tag":521,"props":749,"children":750},{"style":550},[751],{"type":75,"value":752}," forward",{"type":61,"tag":521,"props":754,"children":755},{"style":544},[756],{"type":75,"value":757}," --bucket",{"type":61,"tag":521,"props":759,"children":760},{"style":550},[761],{"type":75,"value":762}," flask-hooks",{"type":61,"tag":521,"props":764,"children":765},{"style":550},[766],{"type":75,"value":767}," http://localhost:5000/webhooks\n",{"type":61,"tag":62,"props":769,"children":770},{},[771,773,779,781,787,789,793],{"type":75,"value":772},"Paste the bucket's public URL into the provider's webhook settings. Each request is delivered to Flask and recorded, so you can inspect the payload and replay it after you change your code. Read the raw body with ",{"type":61,"tag":70,"props":774,"children":776},{"className":775},[],[777],{"type":75,"value":778},"request.get_data()",{"type":75,"value":780}," before parsing JSON if you ",{"type":61,"tag":273,"props":782,"children":784},{"href":783},"/glossary/webhook-signature/",[785],{"type":75,"value":786},"verify the signature",{"type":75,"value":788},"; re-serialised JSON won't match the HMAC. The ",{"type":61,"tag":273,"props":790,"children":791},{"href":23},[792],{"type":75,"value":24},{"type":75,"value":794}," post is a full walkthrough.",{"type":61,"tag":62,"props":796,"children":797},{},[798],{"type":75,"value":799},"To show the whole app to someone, use a tunnel instead:",{"type":61,"tag":511,"props":801,"children":803},{"className":513,"code":802,"language":515,"meta":7,"style":7},"relay connect --name my-flask-app http://localhost:5000\n",[804],{"type":61,"tag":70,"props":805,"children":806},{"__ignoreMap":7},[807],{"type":61,"tag":521,"props":808,"children":809},{"class":523,"line":524},[810,814,819,824,829],{"type":61,"tag":521,"props":811,"children":812},{"style":538},[813],{"type":75,"value":747},{"type":61,"tag":521,"props":815,"children":816},{"style":550},[817],{"type":75,"value":818}," connect",{"type":61,"tag":521,"props":820,"children":821},{"style":544},[822],{"type":75,"value":823}," --name",{"type":61,"tag":521,"props":825,"children":826},{"style":550},[827],{"type":75,"value":828}," my-flask-app",{"type":61,"tag":521,"props":830,"children":831},{"style":550},[832],{"type":75,"value":833}," http://localhost:5000\n",{"type":61,"tag":62,"props":835,"children":836},{},[837],{"type":75,"value":838},"It prints a public HTTPS URL that stays the same if you reuse the name.",{"type":61,"tag":840,"props":841,"children":842},"style",{},[843],{"type":75,"value":844},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":556,"depth":556,"links":846},[847,848,849,850,851,852],{"id":107,"depth":534,"text":110},{"id":286,"depth":534,"text":289},{"id":405,"depth":534,"text":408},{"id":506,"depth":534,"text":509},{"id":660,"depth":534,"text":663},{"id":717,"depth":534,"text":720},"markdown","content:localhost:5000.md","content","localhost/5000.md","localhost/5000","md",{"loc":4},1793199809151]