"IPv6 is weird. One of the more strange parts of the standard is that every interface's link local addresses are in fe80::whatever`."
How is IPv6 weird here, it's the exact same thing in IPv4, no? If you have two different network interfaces, you have to identify which is which somehow, either by assigning a specific IP range to it or by adding some kind of identifier.
Making zones part of addresses in the first place was probably a mistake, I agree, but the problem of address conflicts when users can choose arbitrary addresses certainly isn't a design flaw of IPv6.
I think the weirdness comes from the use of multiple addresses at once, specifically fe80::whatever addresses always being present and getting used even on normal setups when everything's working fine and a global address is configured, as opposed to 169.254.whatever addresses, which most networks never intend to use and so usually only show up when something is wrong.
There aren't address conflicts. And users aren't choosing this, it's part of the IPv6 spec. Each interface has a unique address, but you can't tell from looking at an address which network it lives on.
> In order to disambiguate what's the host and what's the port, you typically format the IPv6 address in square brackets, so fe80::4 on port 80 would look like this:
> [fe80::4]:80
I really do wish they'd just stuck with dots. Or if we must upend things, commit to the bit and change the character to separate ports.
Yeah. I think that's actually my one, biggest gripe about IPv6, those damn colons. And those damn brackets that were made to mitigate the colons, that just cause more problems:
Just yesterday I tried to use rsync (like I do all the time, in my mind there's no reason to use scp when rsync does everything better), but this time I needed to specify an IPv6 address. On the (admittedly ancient) rsync version that comes with macOS, this doesn't work:
rsync foo 'user@[fe80::4]:/tmp'
Note how I had to put the second argument in quotes, because otherwise the shell tries to expand the square brackets as filename expansion.
But even then rsync just complains, because rsync itself separates host from path through colon. I think the only workaround is to do something like `rsync -e 'ssh user@[fe80::4] ...'`... but I just used an updated rsync from homebrew, which is of course the saner method. Still, just another colon/bracket-caused issue.
I ran into some of these issues when working on IPv6 validation in a library. I found that if you just call system functions like inet_pton, you would also get OS-dependent restrictions on what zone identifiers are valid! This isn't ideal so I wound up just making an IPv4/IPv6 parser with a very liberal zone ID production. Said library also supported URLs, and I did not implement it to parse the IPv6 literal as percent encoded in this edge case, but it winds up working both ways anyways. Is this good? Maybe not: maybe it would've been better to pick a strict subset instead. However, whether or not that would be better depends on specific use cases. Unfortunately, there is just no perfect answer sometimes.
I wonder why IPv6 didn't catch on! It's just unergonomic and ugly!
At work, I have a rare case of a useful application of IPv6: setting IPv4 addresses. We have multiple embedded devices in one product which all got the same default IPv4. But their serials map to their MACs which map to their link-local IPv6.
So workers scan the serial and I connect to all devices at once via their IPv6 address. Then, I set their individual IPv4 address and that's all I do via IPv6.
Which says that, yes, you need to %-encode the %, so a URL containing a host of fe80::4%eth0 becomes http://[fe80::4%25eth0]/. Yes, that's ugly. Sorry.
> TL;DR: computers were a mistake.
I agree entirely.
(For what it's worth, I am a maintainer of Go's net/url package, and I believe net/url correctly handles zone ids in URLs. It's always possible there's something wrong I'm not aware of. Please let me know if there is!)
> This document completely obsoletes [RFC6874], which implementors of web browsers have determined is impracticable to support [LINK-LOCAL-URI], and replaces it with a generic UI requirement. Note that obsoleting [RFC6874] reverts the change that it made to the URI syntax defined by [RFC3986], so [RFC3986] is no longer updated by [RFC6874]. As far as is known, this change will have no significant impact on non-browser deployments of URIs.
Who says Go's handling of the corner case is incorrect? The original IPv6 RFCs didn't address the case at all. Then in 2013 RFC6874[1] clarified that the % in the zone identifier MUST be percent encoded when used in a URI, just like Go requires. Then in 2025 this RFC was obsoleted by RFC 9844, which only talks about UI behavior and says nothing about URIs, basically reverting things back to the undefined state prior to 2013. What a fucking mess.
Are URLs of link local addresses a common thing with IPv6? I don’t think I’ve ever encountered one myself (but my home network supports ULAs and more importantly DNS).
Think of that you want to Provision a "smart device" with just a computer and no router.
These link local addresses are quiet handy. But sadly the parsing of these with modern browsers is a flame war ever since. I assume that's the reason why we don't see its usage that often.
Another nice use case is to use these link local addresses in cloud environments...
Also, thank you windows for not having consistent interface ids after reboot. I had to rewrite a configuration file every startup with powershell in order to tackle this case.
You complain about URL encoding ? Enter UNC encoding ...
https://devblogs.microsoft.com/oldnewthing/20100915-00/?p=12...
> \\fe80--1ff-fe23-4567-890as3.ipv6-literal.net\share
"IPv6 is weird. One of the more strange parts of the standard is that every interface's link local addresses are in fe80::whatever`."
How is IPv6 weird here, it's the exact same thing in IPv4, no? If you have two different network interfaces, you have to identify which is which somehow, either by assigning a specific IP range to it or by adding some kind of identifier.
Making zones part of addresses in the first place was probably a mistake, I agree, but the problem of address conflicts when users can choose arbitrary addresses certainly isn't a design flaw of IPv6.
I think the weirdness comes from the use of multiple addresses at once, specifically fe80::whatever addresses always being present and getting used even on normal setups when everything's working fine and a global address is configured, as opposed to 169.254.whatever addresses, which most networks never intend to use and so usually only show up when something is wrong.
Isn't 127/8 always present in IPv4, without I'll consequences?
There aren't address conflicts. And users aren't choosing this, it's part of the IPv6 spec. Each interface has a unique address, but you can't tell from looking at an address which network it lives on.
The title of the post suggests the issue is allowing that syntax in URLs.
Is there an equivalent syntax for IPv4 addresses?
> In order to disambiguate what's the host and what's the port, you typically format the IPv6 address in square brackets, so fe80::4 on port 80 would look like this:
> [fe80::4]:80
I really do wish they'd just stuck with dots. Or if we must upend things, commit to the bit and change the character to separate ports.
an IPv6 address has 16 bytes.. so in dot notation it would look like this:
`32.1.13.184.133.163.0.0.0.0.138.46.3.112.115.52`
Is that an improvement?
> I really do wish they'd just stuck with dots
Then it would get confused with domain names (e.g. babe.cafe).
Ah, right, because we threw in hex. That's fair, but then I return to: If we're doing that, we should have changed the port separator.
Yeah. I think that's actually my one, biggest gripe about IPv6, those damn colons. And those damn brackets that were made to mitigate the colons, that just cause more problems:
Just yesterday I tried to use rsync (like I do all the time, in my mind there's no reason to use scp when rsync does everything better), but this time I needed to specify an IPv6 address. On the (admittedly ancient) rsync version that comes with macOS, this doesn't work:
rsync foo 'user@[fe80::4]:/tmp'
Note how I had to put the second argument in quotes, because otherwise the shell tries to expand the square brackets as filename expansion.
But even then rsync just complains, because rsync itself separates host from path through colon. I think the only workaround is to do something like `rsync -e 'ssh user@[fe80::4] ...'`... but I just used an updated rsync from homebrew, which is of course the saner method. Still, just another colon/bracket-caused issue.
I ran into some of these issues when working on IPv6 validation in a library. I found that if you just call system functions like inet_pton, you would also get OS-dependent restrictions on what zone identifiers are valid! This isn't ideal so I wound up just making an IPv4/IPv6 parser with a very liberal zone ID production. Said library also supported URLs, and I did not implement it to parse the IPv6 literal as percent encoded in this edge case, but it winds up working both ways anyways. Is this good? Maybe not: maybe it would've been better to pick a strict subset instead. However, whether or not that would be better depends on specific use cases. Unfortunately, there is just no perfect answer sometimes.
> And with the right scope it looks like this:
> Now let's get URL encoding into the mix. ...About here my I felt my heart start to beat really fast and I started to hyperventilate.
I'll just accept that this is as much of a nightmare as it seems.
I wonder why IPv6 didn't catch on! It's just unergonomic and ugly!
At work, I have a rare case of a useful application of IPv6: setting IPv4 addresses. We have multiple embedded devices in one product which all got the same default IPv4. But their serials map to their MACs which map to their link-local IPv6.
So workers scan the serial and I connect to all devices at once via their IPv6 address. Then, I set their individual IPv4 address and that's all I do via IPv6.
> In theory, there is guidance for how to properly handle IPv6 zones in user interfaces in RFC 9884, but there's no such guidance for URLs.
RFC 6874: Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers (https://www.rfc-editor.org/rfc/rfc6874.html)
Which says that, yes, you need to %-encode the %, so a URL containing a host of fe80::4%eth0 becomes http://[fe80::4%25eth0]/. Yes, that's ugly. Sorry.
> TL;DR: computers were a mistake.
I agree entirely.
(For what it's worth, I am a maintainer of Go's net/url package, and I believe net/url correctly handles zone ids in URLs. It's always possible there's something wrong I'm not aware of. Please let me know if there is!)
That RFC is obsoleted by https://datatracker.ietf.org/doc/html/rfc9844 which removes all guidance around URIs:
> This document completely obsoletes [RFC6874], which implementors of web browsers have determined is impracticable to support [LINK-LOCAL-URI], and replaces it with a generic UI requirement. Note that obsoleting [RFC6874] reverts the change that it made to the URI syntax defined by [RFC3986], so [RFC3986] is no longer updated by [RFC6874]. As far as is known, this change will have no significant impact on non-browser deployments of URIs.
I have published a fix to the post, it should be live within a minute. Thanks!
https://github.com/Xe/site/commit/f846b489092412b8c1ef70bebd...
The sibling comment to yours may be useful:
https://news.ycombinator.com/item?id=48405808
i hate computers
Nothing is more idiomatic Go than ignoring inconvenient edge cases.
Who says Go's handling of the corner case is incorrect? The original IPv6 RFCs didn't address the case at all. Then in 2013 RFC6874[1] clarified that the % in the zone identifier MUST be percent encoded when used in a URI, just like Go requires. Then in 2025 this RFC was obsoleted by RFC 9844, which only talks about UI behavior and says nothing about URIs, basically reverting things back to the undefined state prior to 2013. What a fucking mess.
[1] https://www.rfc-editor.org/info/rfc6874/
[2] https://www.rfc-editor.org/info/rfc9844/
Added to https://github.com/globalcitizen/taoup/
Are URLs of link local addresses a common thing with IPv6? I don’t think I’ve ever encountered one myself (but my home network supports ULAs and more importantly DNS).
Think of that you want to Provision a "smart device" with just a computer and no router.
These link local addresses are quiet handy. But sadly the parsing of these with modern browsers is a flame war ever since. I assume that's the reason why we don't see its usage that often.
Another nice use case is to use these link local addresses in cloud environments...
No. A well set up network never needs them at all. But I can see the usefulness
Also, thank you windows for not having consistent interface ids after reboot. I had to rewrite a configuration file every startup with powershell in order to tackle this case.
TL;DR: computers were a mistake.
Honestly, I can't really say he's wrong...
I don't even understand what's being complained about here. If you want a % in a Uri you need to encode it. It's not rocket science
Except that % is already used to encode something else.
Now if someone else a URI, is there going to be any confusion on how many times a URI needs to be decoded?
If the answer is yes, then we have a problem.
(and by looking at the other comments in this thread, the answer is most definitely yes)