140 comments

[ 4.6 ms ] story [ 227 ms ] thread
This was discussed before: https://news.ycombinator.com/item?id=29006861

Their usage of port 5000 appears compliant with IANA port designation.

Developers trying out their web servers should probably add another zero for port 50000 and now they'd suddenly get an IANA compliant one.

I'm not sure how this came to be to be honest. This is a very old system, but yet we still abuse the four digit range with private use ports. I mean, it's often just one digit away. Even as defaults in software packages where their developers should at least know better even if a random web developer might not.

Or we stop pretending this IANA document means anything and make software that is shipped on millions of computers by default use port numbers that don't take away from what humans prefer to use?
> Or we stop pretending this IANA document

Yeah, and while we're at it, let's burn all IETF RFCs. Who needs that?

The point is that even the IANA doesn't give a fuck about the port assignment document. It's full of dead entities.
That is rather an audacious statement. Company dead != unused. Also, the process is well-defined and guided by an RFC itself, so it's really in IETF's control, just stewarded by IANA.
Like, how Linux DEs change their standard APIs so often that unless you've targeted X, it sucks? There are reason for having sensible standards. You can say something bad about Windows, but the paramount stabilty (despite their multiple changes in theming) is very appreciated, thank you.
It's not a standard if it was never adopted. The port assignment document has two practical uses:

1) To cite it in a smart hacker news comment 2) To show alarming text in "security scans" to gullible people

Seriously, google "commplex" and all you find is confused home users thinking they got a trojan of sorts. In 2021, it is purely a drain on everyones nerves.

What about Dns, smtp, http, https, ftp, ssh, sftp, etc.?

Pretty sure those are not drains on everybody's nerves. Devs bashing standards cause they don't want to follow the rules which make things work well is a drain on everyone's nerves.

But maybe I have misunderstood the document (didn't read). Standards are nice, except when they are mostly geared towards one company. Then yeah, it would be better to have SRV records and discourage default port usage such as Apple is doing.

If we could go back in time, forcing an app layer (e.g. an ssh header) over a port might have been helpful, port conflicts might have been less common and you could have even eliminated root only ports.

At any rate let's not break the web because some lazy mofo doesn't want to get off their couch.

>Like, how Linux DEs change their standard APIs so often that unless you've targeted X, it sucks?

AFAIK that's mostly a GNOME issue, so despite it wrongly, IMO, being the default and the most popular DE of the Linux distros for some reason, I wouldn't throw mud on the whole Linux DE ecosystem because of it alone.

KDE, LXQT, LXDE and XFCE seem to have their shit together for the most part.

KDE ain't too, unfortunately, and really unrelated to Qt. I'm using Plasma right now, but that transition was rough, and unrelated to it's refresh.
Would you mind detailing why you think KDE isn't?

I'm no fanboy and have no dog in this DE fight, just curious.

If you wrote without KDE dependencies and your distro did include the correct Qt version, there's no problems at all (apart from edge-case bugs). But KDE3 to KDE4 and KDE4 to KDE5 (Plasma) was associated with a whole change, similar to Mozilla's Firefox's "Daylight", "Quantum", and "Australis" and web extensions, and associated behavioural relearings.
I thought we were talking about the present situation of KDE, not about past history.
What we should really do / have done is add port numbers to DNS entries. Then IANA wouldn’t need a public registry of port assignments. Everyone can use whatever ports for our public services that we like.

Sadly, its almost certainly too late to add port numbers to DNS.

that's exactly what SRV records do. Used for many things, but not HTTP(S)
Actually, DNS SRV entries do support port numbers (and transport layer!) https://en.wikipedia.org/wiki/SRV_record

It is just a matter of specifying the use of such entries in the protocols (HTTP et al). A lot of new protocols already rely on them.

As someone who doesn't do much infra, I've encountered them when setting up the DNS for a Minecraft server. The game checks for the SRV record, or if it is missing, assumes (or reads from the user) a given port.

Thats cool!

Do you know what the rationale is for not adding them to HTTP2 / HTTP3?

Sorry, absolutely no idea.
(comment deleted)
I'm to blame for 5000 being popular as HTTP port as I picked it by default for Flask. The reason I did this was that there is only one HTTP port (other than 80 you can't bind to) in the IANA registration which is 8080. A few people started using other ports around the time because 8080 was commonly already occupied by some userspace HTTPDs.

I picked specifically 5000 because the IANA registration for this port was assigned to a single service, was not used and generally obscure. Whatever Apple has running on there is also unlikely to be what the IANA registration refers to.

> Whatever Apple has running on there is also unlikely to be what the IANA registration refers to.

Here's a quotation:

> Just did a bit more digging, and IANA actually assigns port 5000 to "commplex-main" - so really any other service that's using that port is violating the official assignment. Based on a quick search of what commplex-main is, it's related to UPnP for network device discoverability. I'm not sure exactly what the AirPlay Receiver service does, but I get the gist that it probably does fit somewhere into the scope of UPnP-related features. At the very least, it's probably a far more accurate usage of port 5000 than some random dev servers.

This port was actually also used back in XP and * Lion days both by Apple and Microsoft, but I have a hunch that *.local replaced these use cases and that's why it became disused until recently.

I believe that comment to be incorrect. UPnP is using this port, but unofficially. The IANA port registration for 5000 is for commplex whatever it is, and it refers to two ports: 5000 and 5001. UPnP uses 5000 unofficially and does not use 5001.
Does Multiplex Communication sounds familliar? But yeah, someone should check the IANA archives to know what really is "commplex-main".
It would appear commplex was a part of seeplex, some visualization tool for old Sun workstations in the early 90ies: https://lib.dr.iastate.edu/cgi/viewcontent.cgi?article=11617...
It's actually called "Triplex", Commplex and Seeplex are part of Triplex.

> The Commplex is a communications package for communication with the NCUBE from Sun workstations.

Wait, all roads lead to Oracle?

So, uhm, this reminds me of STMPS and port 465. Read about it, and it's a sad state of affairs because of a blunder in managing that list. Funnily, mail providers and Cisco share that port (and no, not a TCP/UDP split, both are for TCP connections).

So who suggested to use port 5000 then way back? That's a serious question that is now my homework for this conversation.

I'm not quite certain how common it really is. But, in any case, ports are expected to occasionally collide and therefore easy to configure.

If port collisions were such a hassle, we wouldn't see anything like a "common" port (i. e. one that unrelated tools choose per default).

Good developers can have a pipe in every port, I guess...

(valid for development work only, especially those cases where you run some server and it opens the browser for you, port helpfully provided. There is value in ssh on 22 and http on 80, obvsly)

Judging by that thread in the Apple forums, people are for some reason unable to change the default port their development environment uses, so they blame Apple for using a port they have been using for a long time. Not sure why they are unable to change them, but the typical Apple user isn't directly famous for their willingness to configure their own software (either changing the ports of their development environment, or configure their OS to stop using that port), so I guess it's fairly common to end up with scenarios like this.
Using whole round numbers like 5000 for public release software is pretty braindead though.
Are ports 1-4999 already in use? Can we reserve a private area like 192.168/24 for IPs?

Also why is there no official TLD for DNS for local domains?

The first 1024 are reserved and you usually can freely choose the ones greater than that. You can also use .local for local domains.
Using .local is no longer recommended since it's used for mDNS. Apple devices in particular have issues resolving .local addresses.

Current best practice is to use a subdomain of a domain you control for internal stuff. Makes getting certs for internal hosts easier too if you can be bothered.

1-1024 are reserved for root so you can still technically use them. Port 0 is the only one truly reserved/impossible to used
You can use the .local, .localhost, .example, and .test TLDs for local domains -- these are IANA reserved: https://www.iana.org/assignments/special-use-domain-names/sp...
.local is used for mDNS these days, don't use it if your network has Apple devices.
not just Apple devices, you'll find mDNS resolvers on many setups. Overrides in the hosts file might be fine, but still, I'd avoid it.
> don't use it if your network has Apple devices.

As of now, but something about IPv6 also forced Microsoft to implement this, and some Linux distros also does this in CUPS (I know it's Apple...)

.home and .corp are also kind of available. They are reserved so they won't ever be made available but aren't officially recognised as special use domains.

I use .home and it's fine, but there's the occasional oddity when e.g. Chrome doesn't recognise "myserver.home" as a FQDN as ".home" isn't on its built in list of TLDs

'.dev' was bought for the purpose of "never using it" but then Google went and started using it.

So, there's at least _some_ precedent that previously reserved things become unreserved :(

Yeah I don't think that's how it happened
That's literally what happened though; Heres the first result I found that talks about them opening up .dev and it literally says "Intended for internal use at Google Only". Though they don't provide additional citations, it's commonly understood that this was the reason it was acquired.

https://www.searchenginejournal.com/google-opens-up-dev-doma...

"intended to be private and reserved for Google’s use only"

That's a lot different from "never using it" and it isn't like they publicly made a pledge that was what they were going to do with it...

Ok, but the request: https://gtldresult.icann.org/application-result/applications...

says: “The proposed gTLD will provide Google with direct association to the term “dev,” which is an abbreviation of the word, “development.” The mission of this gTLD, .dev, is to provide a dedicated domain space in which Google can enact second-level domains specific to its projects in development.”

and goes on to say:

> “18(b). How do you expect that your proposed gTLD will benefit registrants, Internet users, and others?

> Given its intended use by Google, the .dev gTLD will best add value to the gTLD space by remaining completely closed for the sole use of Google.”

And finally:

> “18(c). What operating rules will you adopt to eliminate or minimize social costs?

> Members of the public will not be able to register domain names in this new gTLD.”

Those statements don't really say that none of the .dev domains will ever resolve, only that all .dev domains that do resolve will point to Google projects that are "in development" (which either means services that haven't officially launched yet or services that aren't deprecated yet, depending on interpretation).
Are you sure you want to make the argument that because words can be interpreted in their least charitable way that that’s what the intention really was?

Reading that proposal is _clear_ to me that it’s for internal use only and that the impact to the global internet is that “it does not exist”. (And even hinting that it’s a good thing).

Obviously they never _comitted_ to never using it, but it is absolutely apparent that their intent was “internal to google, unused outside” and given how poisoned the .dev namespace was already at that time: it was met with somewhat apprehensive open arms.

Google then went and opened it and made it impossible to use locally by pinning HSTS on the TLD level. Which is basically the worst thing they could have done with it, given that people were using it locally already.. and some popular frameworks even recommended it as an option when running locally.

(Though, there is an argument to be made there that they made sure things worked as expected by forcing the public use of .dev)

Obviously it’s fine now. But don’t pretend this was obvious.

> Though they don't provide additional citations

It's in their gTLD application for .dev[1]

> The mission of this gTLD, .dev, is to provide a dedicated domain space in which Google can enact second-level domains specific to its projects in development. Specifically, the new gTLD will provide Google with greater ability to create a custom portal for employees to manage products and services in development.

> Charleston Road Registry believes that given its intended use by Google, the .dev gTLD will best add value to the gTLD space by remaining completely closed for the sole use of Google.

[1]: https://gtldresult.icann.org/applicationstatus/applicationde...

That's quite different from reserved to be never used. And even if that had been the goal, it's still quite different than TLDs where ICANN has said they won't delegate them. (Which in turn are arguably weaker than ones that are reserved by an actual internet standard, although I suspect .home and .corp are more than poisoned enough. For $reasons the standard says .home.arpa and .corp.arpa, which nobody ever uses)
I don't think IANA explicitly reserved .dev. It was made popular as a local dev domain by Basecamp's Pow[1] and Laravel Valet[2]. IANA only defines .test, .example, .invalid, .local, and .localhost as reserved (with .onion being the latest addition in 2015[3])

Though in this list, only .test and .example are marked as non-special and must be resolved normally by RFC 6761, and .local is reserved for mDNS by RFC 6762. In this list, .test would have been the most appropriate for Pow to use.

CydeWeys (Tech Lead of Google Registry) has commented on HN in the past that they did not anticipated people weren't following the best practices[4], which makes me think IANA should have given .dev the same treatment as .onion: by explicitly reserving them (but this is another topic to discuss).

[1]: https://github.com/basecamp/pow

[2]: https://github.com/laravel/valet

[3]: https://www.rfc-editor.org/rfc/rfc7686.html

[4]: https://news.ycombinator.com/item?id=24606714

My OpenWRT router uses .lan and that seems to work ok.

Especially with short hostnames like pi.lan :)

Is that forum post's poster so lazy or incompetent that they cant change a port in their development config file ?
I think it is more about defaults. 5000 is the default port for flask framework, changing the port to make the app working for first time can be painful given the developer have to google why the default port isn't working anymore
If you’re a developer and you need to Google what to do about a port conflict… better put some more time in.
About 99% of the graduates of "coding bootcamps" won't ever have heard what a "port" even is.
It would be lazy not to investigate why something that has worked for years suddenly broke upon OS upgrade.
You're expecting too much, the reason developers use macOS in the first place is to not having to consider the entire of their environment. They rather call a number and have someone solve it for them, than investigating why a OS update broke something, otherwise they'd use a OS that required them to understand the full stack from the beginning.
As repeatedly pointed out, Apple has been using these ports for audio streaming functionality since 2004. If your web framework is so inflexible that it hard-codes ports to collide with OS functionality without an easy way of reconfigure it, that's on the framework, no?
what if there IS an easy way to do it, as is the case here?
Then you don't post a new thread ;)
On airports or what? I used Mac as my development environment for ten years and never had a conflict using port 5000. It’s not about inflexible web frameworks, lazy or stupid developers that use Macs. 5000 is a popular default port for web frameworks, and if it stops working one day, there’s nothing wrong with wondering why. It might be a small headache to get your entire team to redefine the default port in your project’s dev environment if half of them use another OS, or you happened to upgrade MacOS before everyone else. Of course, the most likely outcome will be switching to another port, but what is with all the hostile comments in this thread about someone asking why something that’s worked for so long broke?
It hasn't 'broke' - the latest OS update includes functionality for macs to operate as an Airplay host and so the port they've always used for that functionality is now used by this new feature.
System programmers and project managers for airplay are probably not familiar with popular web frameworks. Besides that this usage is secondary to a public service. If a developers workflow Is so brittle as such an inconsequential change is enough to create a burst of outrage, this developers workflow sucks. You shouldn’t expect a port to be available and hard code them all over your configuration. Use the opportunity to refine your craft and make your development practices more repeatable and deliberate.
Of course there is no problem with asking why things broke and how to fix them. My comment was however directed at the silly fad of blaming Apple for all and everything, because “big corp always bad and FOSS always guud”. This is irrational, unfair and anti-intellectual. There are more then enough valid reasons to criticize Apple. In this particular instance however they did not do anything wrong. So yes, if one spins the tale like it’s “evil Apple” deliberately breaking everyone’s work environment again (with Tim Cook supposedly maniacally giggling in the background), will indeed be met with a hostile response from my side.
The problem is not the inflexibility of frameworks - it is that, once the frameworks adapt to the change, a lot of guides, stackoverflow posts etc. will break and people will blame the framework for the issues.
What web framework commonly uses 5000 in development mode? I've seen a lot of port 3000 and 8888 and 8080 and 10000, but never 5000.
Flask, svelte.js' "sirv", angulars "ng serve", ASP.NET
Angulars "ng serve" defaults to 4200 as far as I'm aware; never seen 5000 in the wild in the context of Angular
(comment deleted)
we ran into it recently, basically when running microservices locally the different services were running on different ports, obviously don't need all running but there was a collision. The main problem is that with Apple's normally great communication skills about what they do, it takes a while to figure out what has all of a sudden happened and then change your port. And then you're mad at apple for making you waste some time.
Looking at open ports takes a while?
one of the things I often hear is that people don't like to go repeat the same action a bunch of times, so for example if one has a bunch of microservices meant to be run through docker one does not want to go set ports up for all scenarios etc. and to have every member of a team do the same thing, and maybe updating documentation because you've written in port 5000 all over the place, hah hah, but no to answer your no doubt sincere question looking up open ports does not take a while.

What takes a while is another engineering principle that people are sometimes bitten by, trying to understand why a change in the system has occurred - in this case why your port that you always use is suddenly no longer open despite you not having done anything that you are aware of that might have closed it. Of course you want to understand why this change has happened because it seems weird, is there something nefarious going on at port 5000 now!?! Also because of all the things said above about wanting to not change all occurrences of 5000 in your developer docs and so forth so it would be nice if you figure out, as was shown as the top voted answer of the article, that you could go to somewhere in settings and turn off this usage of the port. I mean you could just scan and change what port you use to another currently open port without worrying about any of this stuff, which I guess would have worked in this case but I can't help but feel that would not really appear the best move whenever strange unexplained port usage changes occur. Your mileage evidently varies.

Not a web framework but running a local docker registry uses port 5000 by default
It is easy to bash those complaints, but it does show that the IANA port assignments [1] do not work well for ports 1024-- in practice. You generally don't see this kind of complaints for system ports (0--1023) because you need root for them in UNIXish systems and thus has a much higher bar for collision. If we were enfocing the same rule for ports 1024-- we should have overflown the IANA registry by now [2], but it will be absurd and we instead collectively chose to ignore the registry. It hardly makes a difference whether you have actually registered your port to the registry or not; you should prepare for a possibility that your use of that port collides with other's.

[1] https://www.iana.org/assignments/service-names-port-numbers/...

[2] The actual rate is something like 3--50 new and updated entries per year.

I hope you're not advocating the return of the portmapper?
~1 month ago, when setting up my new Macbook it took me forever to debug this. After hours of trying to mess with the builtin Apache service (thinking it was the culprit), I found a random blog post that said to disable the sharing feature occupying the port in the system preferences. It was devilishly hard to debug (and google for) at the time.

For those wondering why I needed port 5000 in my case, it was a standard Svelte app serving on localhost:5000 (via Sirv).

Doesn't something like `lsof -i TCP -s TCP:LISTEN` quickly show what's monopolizing 5000?
Does lsof show that 5000 is in use?

Is Svelte hard-wired to 5000?

I didnt try lsof. I figured it was a permissions issue and started going down the Apache rabbit hole since when trying localhost without a port it displayed a page with "it works"... I thought it had monopolized the whole localhost. Svelte is not hard-wired to 5000, but I made it a point to fix it since I didn't like the idea of a random port being blocked.
Walk the OSI model next time instead. :)
It’s interesting that you thought it was a permissions issue, which suggests that Svelte didn’t report that the port was in use - at least not in clear enough language.

I started off thinking it was a bit ridiculous that people developing wouldn’t just think ‘oh port 5000 is busy - let me try -p 6000 when running this’ but I see that was a wrong assumption, because the tool itself seems to perhaps be flawed in that it isn’t making it easy to diagnose and change how it runs to sidestep the used port.

Perhaps a feature request for svelte is in order?

Others have suggested `lsof` to find out which ports are in use and by whom. I'll also add `netstat -nlp` or the more modern `ss -ntlp` to achieve the same. They will show you which process is listening on which TCP port (with these flags).
Will use next time! thanks for the tip.
No problem! We all know some limited amount about the huge computing environment, and accumulate solutions as we hit problems.
Can't check myself, because I am not using MacOS, but isn't `ss` linux-specific? I think it still is (and will be) `netstat` on MacOS and BSDs?
Don't use MacOS or any BSD, so you are quite possibly right.
Every time I've written something that uses a port I've added a check to see if the code returns an EADDRINUSE error when the listener connects, and offered the user an alternative port if it does. I always assumed everyone did that but apparently not. Maybe I should make an NPM package...
It should be a Pip package instead!

(The main non-IANA compliant user of the port is Flask, a Python-based web framework.)

No one would want to use a Python package written by a JS developer. :)
No one would see any difference, any perceived difference in quality is a meme
I don't know, if you'd never done any Python, and perhaps particularly if you learnt JS in 'callback hell' days, you might not realise what was wrong with:

    def doSomething(theArgs, cb):
        food, bard = 0, 0
        try:
            doFoo(theArgs["foo"], lambda: food = 1)
            doBar(theArgs["bar"], lambda: bard = 1)
        except Exception:
            cb(food + bard, "didn't work")
        else:
            cb(food + bard, None)
or whatever.

I can get by in JS, I use it professionally even now, but it's not good quality; I know that. (Trivial example, I discovered `??` recently. I've definitely written a lot of null/undefined checks without it, or even naive ternaries that assume non-null/undef values aren't falsey (`thing ? thing : 123` vs. `thing ?? 123`) - which is kind of like seeing `dict.get(key, None)` in python.)

Fun trick I learned: binding to port 0 causes Linux to pick a random, unused, ephemeral port for you. That's what I've started using in my EADDRINUSE fallback.
...it boggles my mind that listening on port 0 and then reporting the actual bound port is not the default. It takes only a couple minutes more to properly write (and another couple of minutes to write the code to properly consume the reported port) but it offers tremendous convenience.
In the case of Flask: It would be incredibly inconvenient to restart your development server and have it show up on a random port every single time.

The only time fixed port numbers are inconvenient is when they conflict, but otherwise they're much easier to work with.

Yes, "worse is better", the ultimate reason of why inferior technical decisions get universally adopted :/

Of course, one day the technical inferiority finally shows itself (e.g., the ports do conflict), and then people start to heroically overcome the obstacles they've created for themselves, showing outstanding feats of ingenuity. Just google "port allocator"! Every company inevitably writes their own home-grown one because everyone's deployment/integration pipeline is unique.

You could always launch once using that scheme, stash the port that you’re offered, and re-use that until it stops working.

It’s likely that the port will be available indefinitely.

> ...it boggles my mind that listening on port 0 and then reporting the actual bound port is not the default.

This already works by just telling flask to use port 0. Binding to port 0 is standard behaviour (literally, part of the standard) and like most other software of that type the first thing Flask does is report the URL it’s running on.

> but it offers tremendous convenience.

Except when it does not as is the case here. If you’re working on your web stuff having to copy/paste a URL from your term every time you restart your server.

> Binding to port 0 is standard behaviour (literally, part of the standard)

I've seen a couple of programs that explicitly check and refuse to start when asked to listen on port 0 (for example, to this day "ssh -D 127.0.0.1:0 remote-host" refuses to start).

> If you’re working on your web stuff having to copy/paste a URL from your term every time you restart your server.

Don't the developer's standard server-launching scripts (re)launch browser after they start the server? IIRC, npm start and VisualStudio+ASP.NET do exactly that.

There are plenty of ports reserved for HTTP without using 5000 - this is a bug in those frameworks using 5000.
I am surprised to see so much comments without mentioning the reason of that (written in the thread)...

* It's the new AirPlay server capability.

* It can be toggled off.

* Those ports are the defaults for AirPlay.

It might've been nice to allow simple way of customizing the ports though..

(comment deleted)
Sidenote: a dispute (https://news.ycombinator.com/item?id=29305298) has been raised on the validity of UPnP even properly using the port. All the details here not contradicting are still correct to the best of my knowledge and research.

Update: "It would appear commplex was a part of seeplex, some visualization tool for old Sun workstations in the early 90ies https://lib.dr.iastate.edu/cgi/viewcontent.cgi?article=11617..."

"The Commplex is a communications package for communication with the NCUBE from Sun workstations."

> * Those ports are the defaults for AirPlay.

No, those are the default port for UPnP discovery, and have been used also by Microsoft in the XP days. There's a reason Apple picked them: it's aligned with their use case, and already assigned by what, 16 years or so?

Probably also the context that you're missing, since that this post is actually somewhat a dupe.

UPnP does not own this port. In the past that also hasn't been much of a problem as the port 5000 was opened by UPnP on the Router, not on localhost where Flask or other web servers are normally listening.
Software should be written under the assumption that any given port can already be in use.
I'm not aware of any software that is not written that way.
Well, apparently Flask or other web dev environments fail to start if their default port is already in use...
That's a misunderstanding of sockets and ports. A port alone is not sufficient for anything, to send traffic across an IP network you need a socket, a socket is tuple of a port and an IP address. When a SERVER "binds" a port, what it's doing is opening a socket for listening against the address specified for binding (generally 0.0.0.0 known as INADDR_ANY).

Sockets cannot collide, therefore you cannot bind more than one service running on a host to the same socket, which means if both are using INADDR_ANY, they cannot use the same port. Nothing prevents you from having multiple IPs on a host, each bound by IP to the same port (which would be separate sockets).

For CLIENT applications, they aren't just utilizing sockets, they're utilizing connections, and a connection is a tuple of two sockets. You can have many many many connections utilizing the same port, as long as they don't collide exactly with the socket on the other side in their signature. There are various ways to handle this, but a typical one is that servers do a hand-off during connection initialization to a temporary port assigned to that connection.

So, Flask (a server), is saying you can't bind it to listen on a socket which is previously bound because it would cause a collision and violate the no-collision rule for sockets. But it doesn't in any way mean that port can't be overloaded by different sockets being bound to the same port.

That’s not the point at all.
Thank you for explaining to me how Berkley sockets work (though you forgot about the protocol identifier, you can absolutely have two sockets listening on 127.0.0.1:8000 as long as one is using TCP port 8000 and the other UDP port 8000).

> There are various ways to handle this, but a typical one is that servers do a hand-off during connection initialization to a temporary port assigned to that connection.

I don't think this is right. Servers don't normally use additional ports. Instead, a process can actually create multiple TCP (streaming) sockets with the same local address:local port combination, but different remote address:remote port combinations (each TCP socket is uniquely identified by a four-tuple).

The point though was that once Flask realizes that it can't bind the address:TCP socket, it shouldn't just give up without even telling users about other options.

> I don't think this is right. Servers don't normally use additional ports. Instead, a process can actually create multiple TCP (streaming) sockets with the same local address:local port combination, but different remote address:remote port combinations (each TCP socket is uniquely identified by a four-tuple).

It's not the only way to address this issue, but it is a common pattern for servers to do a TCP handoff to an ephemeral port during connection initialization. One of the reasons that this is done is because it allows you to have /multiple/ connections from the same client to the same server, which is useful for a number of reasons. You're correct that each TCP connection (which is two sockets, a socket is IP + port) four-tuple with a different remote IP or remote port is considered a separate identifiable entity, so in some cases that means the client is responsible for providing an ephemeral port that should be connected back on. It depends on a variety of factors. If neither side does this, then you are limited to a single connection for that protocol for a single client.

If you'd like to investigate some common servers that use connection handoff and ephemeral ports look at nginx and haproxy, both do this and can also suffer from ephemeral port exhaustion on heavily loaded servers because of it (there are mitigation strategies as well).

I fail to see what other behaviour they could have.

Picking a random port when you have been told to pick a specific port (even implicitly) makes no sense. What if I start flask telling it to use 8000 and it’s already taken by an other program I’m running (something I do semi-regularly as I run tests concurrently), just pick a random port unasked and notify no one about it?

Given how much confusion the current behavior seems to have caused, the best course of action seems to have been a simple:

"Listening on port $PORT. Warning: failed to bind localhost:5000. Start process with --port=$X to specify a different port"

That would be much more helpful behavior and messaging than simply failing, especially since it seems people don't know that they can control the port, and start looking to disabling OS services rather than changing a port...

It might be something to consider, but there are definitely some negative consequences to silently starting on another port, particularly when using automation and tests. It's not fun to have flask silently start on another port and then an integration test hits a completely unrelated service that happens to occupy that port.
Totally agree, but if you're running tests, presumably you are looking for errors in the first place, right? So it doesn't have to fail silently, does it? The testing tools failing for whatever reason seems important to know as well.
> notify no one about it

But why this part? Python -m http.server tells me which port it is using or gives me "OSError: [Errno 48] Address already in use".

In fact, I just tried

python -m http.server $((10000 + RANDOM % 10000))

and it told me what port it started using.

If the suggestion is that Flask should use a random other available port: that could be done, but generally people usually prefer to manually pick a different port themselves. Having a dev server come up on different ports all the time is not a great user experience.
Are you being intentionally obtuse for some reason?
We wouldn't be having this conversation if the web tools were written that way. If the web tool is already running, Airplay will move to another port. The reverse is apparently not true.
Most software has zero need for this.

My company's product contains a web server. We don't bother to check to see if some other program is using port 80 or 443, we just use it. The reason is that we own the machine, we install the software, and we know there is nothing running on these ports; and more, if something is on these ports, we have no way to recover, so terminating abnormally is the right answer.

Neither does Flask and similar, and they are the ones who arbitrarily picked an already-registered port and didn’t bother registering their own.
The port registration system effectively broke down somewhere in the 90ies. There are just too many software projects that need ports in a very limited space. The software we're discussing here (AirPlay apparently) also did not register this port.
(comment deleted)
Why does no web framework let the operating system give them a free port?
Because having the port change on every run is annoying for developers.
And it complicates quickstarts. “Open your browser to localhost:5000” is way easier than “look at the command line, find the line starting with “listening on”, copy the URL (hope you’re not such a beginner you’re unaware it’s C-S-c on linux and have just killed the process scrub), paste that in your browser.
Lots of them do. They try, for example, 8080, then 8081, then 8082, and so on.
Web development frameworks should be easily overridden in case you have other conflicts or want to run multiple apps that default to the same port.
And so is 3000, 8000, 8080, 9000, etc.

... I don't understand the issue as it is easy to change.

Someone moved their cheese.
It's just a pain in larger organizations that's all. I met developers in my life that have no idea how any of the dev env work, they just code, so if setting up docker dev instance fails because of their machine it require someone else involvement and modifications in docs for the future. It's not a big deal but it may be pain in the ass for some organizations.
9000!!! In the PHP Dev environment, 9000 has been used for debugging for over a decade and the fpm-php project comes out and uses 9000 as their default. This is the definition of shooting yourself in the foot. Both solutions can easily switch ports but why choose 9000. It's not like xdebug was an obscure piece of software, it's the most widely used debugger on the platform.
Common where? I never used it in 25 years.
I've noticed a lot of new aspnet core stuff defaulting to using 5000 and 5001 lately, which is kind of weird when you are used to the way that VS used to use IISExpress with a random port number
What common web development server runs on 5000 that wouldn’t automatically increment or throw an error indicating the port desired was occupied and a different one should be used? This seems like a trivial problem.
Because good security practices are so old time.