InetAddress.get*() vs RFC 6724
Robert Stupp
snazy at snazy.de
Mon Feb 9 10:59:18 UTC 2026
Hi Alan,
My question basically came up when I was investigating a network issue
against a dual-stack web site. In my case, there was a routing issue
(somewhere) that affected only IPv4 (packet-loss -> dup-ack), but IPv6
worked fine. So tools like curl/wget, which used the system settings, just
worked without any issue, but the "Java variant" always ran into
that issue. It took me a bit to figure out that IPv4 is by default
preferred in Java, despite the system settings (getinetaddr result). Even
worse for me: the tool I used effectively prevented setting the system
property 'java.net.preferIPv6Addresses=true'.
The crux of such network issues is that those are hard to narrow down,
especially when for example CDNs are in the mix, besides that it requires
networking knowledge.
The question that came up was, whether there's a way to prevent such issues
from bubbling up to users.
Modern web browsers and curl _appear_ to prefer IPv6 over IPv4 by default.
Those use "Happy Eyeballs" (RFC 8305/6555), which is likely a sign that
using IPv6 is (sadly, after ~30 years, sigh) still causing issues for users
[1]. Such HTTP applications probably also use other mechanisms as well [2].
"Happy Eyeballs" is fine for browsers and tools like 'curl', it sits on top
of the lower level InetAddress.get*()/getinetaddr, using their own hostname
resolution and leveraging recent "connection quality" (persisted history).
Changing the default from 'PV4 | IPV6 | IPV4_FIRST' to 'IPV4 | IPV6' in
'java.net.InetAddress' is, no doubt, a change to the observed behavior.
There is certainly a risk that existing applications break with this
change, when suddenly connections are made via IPv6 instead of IPv4. So a
definitive "no go" for released Java versions.
OTOH there's the observed difference between the ordering of the results of
InetAddress.get*() and getinetaddr. I figured that difference a bit
surprising (I never cared about it in the last years TBH, because
everything just worked).
Most code, not just Java, probably just takes the first element returned
by InetAddress.get*()/getinetaddr, which is IMHO not a bad approach,
because there's no, say, "quality metadata" about the individual entries.
I am by no means an expert on the "state of practical use and usability of
IPv6", so my observation is very subjective. Things are, I am sure,
different from ISP to ISP and within organizations' networks and not to
forget interactions with "all the other things".
Options I currently see are (no particular order here):
* "Just"(TM) change the default (tempting, but devils inside).
* Add new InetAddress.get*() functions that allows applications to pass a
lookup preference to use. That would have to work in all cases: v4-only,
v6-only, dual-stack).
* Introduction of a general, inet specific name resolution API (a la
Netty?) with more options.
* Have a "Happy Eyeballs" implementation, raising the questions of where
and how to add it. Naively thinking: something like
'SocketChannel.connect(List<InetSocketAddress> addresses)' and/or
'Socket.connect(List<InetSocketAddress> addresses)'
While it is certainly possible to have a "proper" solution by implementing
custom code or leveraging existing libraries, developers need to be aware
of the potential IPv4/v6 issues when writing code. Having something in the
core Java APIs and/or implementation could help avoiding networking issues
in the broader ecosystem.
WDYT?
Robert
[1] RFC 8305 (https://datatracker.ietf.org/doc/html/rfc8305) says in the
abstract "Since specific addresses or address families (IPv4 or IPv6) may
be blocked, broken, or sub-optimal on a network..."
[2] RFC 9460 (https://datatracker.ietf.org/doc/html/rfc9460)
On Fri, Feb 6, 2026 at 11:45 AM Alan Bateman <alan.bateman at oracle.com>
wrote:
> On 06/02/2026 10:08, Robert Stupp wrote:
> > Hi all,
> >
> > I wanted to test for the appetite to change the current default
> > behavior of the IP address lookup policy on dual-stack (IPv4+IPv6)
> > systems.
> >
> > The default evaluated in InetAddress.initializePlatformLookupPolicy()
> > yields 'IPV4_FIRST' to return IPv4 addresses before IPv6 addresses
> > unless 'java.net.preferIPv6Addresses' is set to 'true'. I wonder
> > whether this could be changed to the system default, relying on what
> > 'getaddrinfo' returns?
> >
> > This would make Java compliant with RFC 6724, which (strongly)
> > recommends to yield IPv6 addresses first.
> >
> > Naively speaking, it can be confusing if something like 'curl' or
> > 'wget' connect via IPv6, but any Java application connects via IPv4.
> >
> > Although it's a tiny code change, it would be a "big" or "surprising"
> > behavior change. Therefore I think, if there's appetite for such a
> > change, it would need to go into one of the next major releases.
> >
> > WDYT?
> >
>
> Moving to net-dev as that is where the networking APIs are maintained.
>
> As an initial comment, changing the JDK to prefer IPv6 addresses by
> default would be a significant and observable change. TBH, I don't see
> this being changed without a wide survey of configurations and a JEP
> that lays out the case and implications of the change.
>
> Is your motive for asking solely because curl/wget tools prefer IPv6?
> I'm wondering if there is more to the question, maybe HTTP protocol
> handler or client only using the first address?
>
> -Alan
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/net-dev/attachments/20260209/472e028b/attachment-0001.htm>
More information about the net-dev
mailing list