| Internet-Draft | Happy Eyeballs v3 | November 2026 |
| Pauly, et al. | Expires 6 May 2027 | [Page] |
Many communication protocols operating over the modern Internet use hostnames. These often resolve to multiple IP addresses, each of which may have different performance and connectivity characteristics. Since specific addresses or address families (IPv4 or IPv6) may be blocked, broken, or sub-optimal on a network, clients that attempt multiple connections in parallel have a chance of establishing a connection more quickly. This document defines the algorithm for "Happy Eyeballs", a technique for reducing user-visible delays on dual-stack hosts. This document updates the algorithm in RFC 8305.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://ietf-wg-happy/draft-happy-eyeballs-v3/draft-ietf-happy-happyeyeballs-v3.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-happy-happyeyeballs-v3/.¶
Discussion of this document takes place on the HAPPY Working Group mailing list (mailto:happy@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/happy/. Subscribe at https://www.ietf.org/mailman/listinfo/happy/.¶
Source for this draft and an issue tracker can be found at https://github.com/ietf-wg-happy/draft-happy-eyeballs-v3.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 6 May 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Many communication protocols operating over the modern Internet use hostnames. These often resolve to multiple IP addresses, each of which may have different performance and connectivity characteristics. Since specific addresses or address families (IPv4 or IPv6) may be blocked, broken, or sub-optimal on a network, clients that attempt multiple connections in parallel have a chance of establishing a connection more quickly.¶
This document defines the algorithm for "Happy Eyeballs", a technique for reducing user-visible delays on dual-stack hosts. This definition updates the description in [HEV2], which itself obsoleted [RFC6555].¶
The Happy Eyeballs algorithm of racing connections to resolved endpoints has several stages to avoid delays to the user whenever possible, while respecting client priorities, such as preferring the use of IPv6 or the availability of protocols like HTTP/3 [HTTP3] and TLS Encrypted Client Hello [ECH]. This document discusses how to initiate DNS queries when starting a connection, how to sort the list of destination addresses received from DNS answers, and how to race the connection attempts.¶
The major difference between the algorithm defined in this document and [HEV2] is the addition of support for SVCB / HTTPS resource records [SVCB]. SVCB records provide alternative endpoints and information about application protocol support, Encrypted Client Hello [ECH] keys, address hints, and other relevant details about the services being accessed. Discovering protocol support during resolution, such as for HTTP/3 over QUIC [HTTP3], allows upgrading between protocols on the current connection attempts, instead of waiting for subsequent attempts to use information from other discovery mechanisms such as HTTP Alternative Services [AltSvc]. These records can be queried along with A and AAAA records, and the updated algorithm defines how to handle SVCB responses to improve connection establishment.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
This document defines a method of connection establishment, named the "Happy Eyeballs Connection Setup". This approach has several distinct phases:¶
Asynchronous resolution of a hostname into destination endpoints (Section 4)¶
Successful establishment of one connection and cancellation of other attempts (Section 6)¶
Note that this document assumes that the preference policy for the destination address family favors IPv6 over IPv4. IPv6 has many desirable properties designed to be improvements over IPv4 [IPV6].¶
This document also assumes that the preference policy favors QUIC over TCP. QUIC only requires one packet to establish a secure connection, making it quicker compared to TCP [QUIC].¶
If the host is configured to have different preferences, the recommendations in this document can be easily adapted.¶
When a client is trying to establish a connection to a named host, it needs to determine which destination endpoint it can use to establish a connection. The client resolves the endpoints by sending DNS queries and collecting the answers. This section describes how a client initiates DNS queries and asynchronously handles the answers.¶
Clients first need to determine which DNS resource records they will include in queries for a named host.¶
This decision is based on whether the client has "connectivity" using IPv4 and/or IPv6 on the current Provisioning Domain (PvD) [PvD]. Generally, "connectivity" for an address family is defined as having at least one non-loopback and and non-link-local ([RFC3927],[RFC4291]) address of that address family from which to send packets, and at least one non-link local route for the address family. When there is IPv6 connectivity, the client MUST include a query for AAAA records. When there is IPv4 connectivity, the client MUST include a query for A records. Additionally, if the client has detected a NAT64 prefix ([NAT64]) on the network, the client MUST include a query for A records (see Section 8 for more details on detecting the NAT64 prefix and handling answers).¶
In addition to requesting AAAA and A records, depending on which application is establishing the connection, clients can request either SVCB or HTTPS records [SVCB]. For applications using HTTP or HTTPS (including applications using WebSockets), the client SHOULD send a query for HTTPS records.¶
All of the DNS queries SHOULD be made as soon after one another as possible. The order in which the queries are sent SHOULD be as follows (omitting any query that doesn't apply based on the logic described above):¶
This ordering assumes that the client implementing the Happy Eyeballs algorithm is able to specifically influence the queries that are sent, or has a guarantee from the DNS stub resolver about how the queries are sent. This is not possible in all environments and operating systems depending on the APIs available.¶
Note that the DNS stub resolver implementation might itself employ the Happy Eyeballs algorithm, particularly when connecting to an encrypted DNS server (using [DOT], [DOH], or [DOQ], for example, potentially discovered via [RFC9461]). Additionally, Section 4.3 of [RFC10001] provides guidance for how stub resolvers ought to handle dual-stack environments. Following this guidance is beneficial to clients implementing Happy Eyeballs, as it ensures that dual-stack networks are handled well during DNS resolution, which is a prerequisite for the rest of the Happy Eyeballs algorithm to work well.¶
Once the client receives sufficient answers to its DNS queries, it can move onto the phases of sorting endpoints (Section 5) and establishing connections (Section 6).¶
Implementations SHOULD NOT wait for all answers to return before starting the next steps of connection establishment. If one query fails or takes significantly longer to return, waiting for those answers can significantly delay connection establishment that could otherwise proceed with already received answers.¶
Therefore, the client SHOULD treat DNS resolution as asynchronous, processing different record types independently. Note that if the platform does not offer an asynchronous DNS API, this behavior can be simulated by making separate synchronous queries for each record type in parallel.¶
The client moves onto sorting endpoints and establishing connections once one of the following condition sets is met:¶
Either:¶
Some positive (non-empty) address answers have been received AND¶
A postive (non-empty) or negative (empty) answer has been received for the preferred address family that was queried AND¶
SVCB/HTTPS service information has been received (or has received a negative response)¶
Or:¶
Some positive (non-empty) address answers have been received AND¶
A resolution time delay has passed after which other answers have not been received¶
Positive answers can be IP addresses received either from AAAA or A records, or IP address hints received directly in SVCB/HTTPS records.¶
Negative answers are exclusively responses to AAAA or A records that contain no IP addresses (with or without an error like NXDOMAIN). If all answers come back with negative answers, the connection establishment will fail or need to wait until other answers are received.¶
On networks that have both default routes for IPv6 and IPv4, IPv6 is assumed to be the preferred address family. If only one of IPv6 or IPv4 has a default route, that address family should be considered the preferred address family for progressing the algorithm.¶
The resolution time delay is a short time that provides a chance to receive preferred addresses (via AAAA records) along with service information (via SVCB/HTTPS records). This accounts for the case where the AAAA or SVCB/HTTPS records follow the A records by a few milliseconds. This delay is referred to as the "Resolution Delay".¶
The RECOMMENDED value for the Resolution Delay is 25 milliseconds.¶
SVCB and HTTPS records describe information for network services. Individual records are either AliasMode or ServiceMode records, where AliasMode requires another SVCB/HTTPS query for the alias name. ServiceMode records either are associated with the original name being queried, in which case their TargetName is ".", or are associated with another service name (see Section 2.5 of [SVCB]).¶
The algorithm in this document does not consider service information to be received until ServiceMode records are available.¶
ServiceMode records can contain IP address hints via ipv6hint and ipv4hint
parameters. When these are received, they SHOULD be considered as positive
non-empty answers for the purpose of the algorithm when A and AAAA records
corresponding to the TargetName are not available yet. Note that clients are
still required to issue A and AAAA queries for those TargetNames if they haven't
yet received those records. When those records are received, they replace the hints
and update the available set of responses as new answers (see Section 4.3).¶
The following examples provide various sequences that might be seen for receiving DNS answers, in order to show how the logic described above is used in practice to determine when to move onto the sorting and connecting phases.¶
A simple dual-stack case where AAAA answers return slight before A answers:¶
A case in which A answers return before AAAA answers, but AAAA answers do arrive after a short delay:¶
A case in which A answers return significantly before AAAA answers:¶
A case in which SVCB/HTTPS answers are slightly delayed:¶
A case in which SVCB/HTTPS answers are significantly delayed, or never arrive:¶
A case in which AAAA answers are delayed, but hints are available:¶
A case in which SVCB/HTTPS answers return with multiple service names ("." indicating that the service applies to the original requested name, and "alt" being an alternative service name). In this case, connection attempts can start in parallel with new AAAA and A queries.¶
An IPv4-only network connection where SVCB/HTTPS answers are slightly delayed:¶
If new records arrive while connection attempts are in progress, but before any connection has been established, then any newly received endpoints are incorporated into the list of available candidate endpoints (see Section 7) and the process of connection attempts will continue with the new endpoints added, until one connection is established.¶
Previously received DNS answers might expire (exceed their TTL) while connection attempts are still in progress. A Happy Eyeballs client will not cancel those ongoing attempts when the answers expire. However, the client MAY trigger new DNS queries to fetch non-expired answers after the original records have expired, in the case in which the original answers have not yet led to a successful connection. Addition of any new answers is handled as described in Section 4.3 and Section 7; that is, ongoing connection attempts will not be cancelled, but any endpoint for which a connection attempt had not yet been started that is no longer in the resolved endpoint list will be removed.¶
Additionally, the fact that Happy Eyeballs enables clients to handle updates to the resolved endpoint list asynchronously enables the use of expired answers "optimistically" while waiting for non-expired answers. This approach is called "optimistic DNS", and is described in [OPTIMISTIC-DNS].¶
Before attempting to connect to any of the resolved destination endpoints, the client defines the order in which to start the attempts. Once the order has been defined, the client can use a simple algorithm for racing each option after a short delay (see Section 6). It is important that the ordered list involves all endpoints from both address families and all protocols that have been received by this point, as this allows the client to get the racing effect of Happy Eyeballs for the entire list, not just the first IPv4 and first IPv6 addresses.¶
The client performs three levels of grouping and sorting of endpoints based on the DNS answers received. Each subsequent level of sorting only changes orders and preferences within the previously defined groups.¶
Grouping and sorting by application protocol and security requirements (Section 5.1)¶
Grouping and sorting by service priorities (Section 5.2)¶
Sorting by destination endpoint preferences (Section 5.3)¶
Clients first group based on which application protocols the destination endpoints support and which security features those endpoints offer. These are based on information from SVCB/HTTPS records about application-layer protocols ("alpn" values) and other parameters like TLS Encrypted Client Hello configuration ("ech" values, see [SVCB-ECH]).¶
For cases where the answers do not include any SVCB/HTTPS information, or if all of the answers are associated with the same SVCB/HTTPS record, this step is trivial: all answers belong to one group, and the client assumes they support the same protocols and security properties.¶
However, the client is aware of different sets of destination endpoints that advertise different capabilities when it receives multiple distinct SVCB/HTTPS records. The client SHOULD separate these endpoints into different groups, such that all endpoints in a group share the same application protocols and relevant security properties. The specific parameters that are relevant to the client depend on the client implementation and application.¶
Note that some destination endpoints might need to be added to multiple groups at this stage. For example, consider the following HTTPS records:¶
example.com. 60 IN HTTPS 1 svc1.example.com. (
alpn="h3,h2" ipv6hint=2001:db8::2 )
example.com. 60 IN HTTPS 1 svc2.example.com. (
alpn="h2" ipv6hint=2001:db8::4 )
¶
In this case, 2001:db8::2 can be used with HTTP/3 and HTTP/2, but 2001:db8::4 can only be used with HTTP/2. If the client creates a grouping for HTTP/3-capable endpoints and HTTP/2-capable endpoints, 2001:db8::2 would exist in both groups (assuming that all other security properties are the same).¶
Connection racing as described in Section 6 applies to different destination endpoint options within one of these groups. The logic for prioritizing and falling back between groups of endpoints with different security properties and protocol properties is implementation-defined.¶
Whether or not specific application protocols or security features are grouped separately is a client application decision. Clients SHOULD avoid grouping and sorting separately in cases where their use of an application protocol or feature is non-critical.¶
For example, an HTTP client loading a simple webpage may not see a large difference between using HTTP/3 or HTTP/2, and thus can group the ALPNs together to respect service-determined priorities where HTTP/3 might be prioritized behind HTTP/2. However, another client might see significant performance improvements by using HTTP/3's ability to send unreliable frames for its application use-case and will group HTTP/3 before HTTP/2.¶
Similarly, a particular application might require or strongly prefer the use of TLS ECH for privacy-sensitive traffic, while others might support ECH opportunistically.¶
Section 8 of [SVCB-ECH] recommends against SVCB record sets that contain some answers that include ECH configuration and some that don't, but notes that such cases are possible. It is possible that services only include ECH configurations on SVCB answers that are prioritized behind others that don't include ECH configurations; for example, this might be used as an experimentation or roll-out strategy. Due to such cases, clients ought not to arbitrarily group ECH-containing answers and sort them first if they won't use the ECH information, or if the connection would not benefit from the use of ECH. However, for cases where there is a reason for an application preference for ECH, the client MAY group and prioritize those answers separately. Even though this might conflict with the published service record priorities, any answers published by the service are eligible to be used by clients, and clients can choose to use them.¶
The next step of grouping and sorting is to group across different services (as defined by SVCB/HTTPS records), and sort these groups by priority.¶
This step allows server-published priorities to be reflected in the client connection establishment algorithm.¶
SVCB [SVCB] records indicate a priority for each ServiceMode response. This priority applies to any IPv4 or IPv6 address hints in the record itself, as well as any addresses received on A or AAAA queries for the name in the ServiceMode record. The priority in a SVCB ServiceMode record is always greater than 0.¶
SVCB answers with the lowest numerical value (such as 1) are sorted first, and answers with higher numerical values are sorted later.¶
Note that a SVCB record with the TargetName "." applies to the owner name in the record, and the priority of that SVCB record applies to any A or AAAA records for the same owner name. These answers are sorted according to that SVCB record's priority.¶
All endpoints received from a particular SVCB service (within a group as defined in Section 5.1), either by an associated AAAA or A record or address hints, SHOULD be separated into a group by the client. These service-based groups SHOULD then be sorted using the service priority.¶
For cases where the answers do not include any SVCB/HTTPS information, or if all of the answers are associated with the same SVCB/HTTPS record, this step is trivial: all answers belong to one group that has the same priority.¶
When there are multiple services, and thus multiple groups, with the same priority, the client SHOULD shuffle these groups randomly.¶
If there are some SVCB/HTTPS services received, but there are AAAA or A records that do not have an associated service (for example, if no SVCB/HTTPS record is received for the original name using the "." TargetName), the unassociated addresses SHOULD be put in a group of endpoints that is prioritized at the end of the list.¶
Within each group of endpoints, after grouping based on the logic in Section 5.1 and Section 5.2, the client sorts the endpoints based on preference and historical data.¶
First, the client MUST sort the endpoints using Destination Address Selection ([RFC6724], Section 6).¶
If the client is stateful and has a history of expected round-trip times (RTTs) for the routes to access each endpoint's IP address, it SHOULD add a Destination Address Selection rule between rules 8 and 9 that prefers addresses with lower RTTs. If the client keeps track of which addresses it used in the past, it SHOULD add another Destination Address Selection rule between the RTT rule and rule 9, which prefers used addresses over unused ones. This helps servers that use the client's IP address during authentication, as is the case for TCP Fast Open [RFC7413] and some Hypertext Transport Protocol (HTTP) cookies. This historical data MUST be partitioned using the same boundaries used for privacy-sensitive information specific to that endpoint, and MUST NOT be used across different Provisioning Domains (PvDs) [PvD]. See Section 9 for discussion around handling multiple PvDs. Implementations that use historical data MUST ensure that clients with different historical data will eventually converge toward the same behaviors. For example, clients can periodically ignore historical data to ensure that fresh addresses are attempted.¶
Next, the client SHOULD modify the ordered list to interleave address families. Whichever address family is first in the list should be followed by an endpoint of the other address family. For example, if the first endpoint in the sorted list has an IPv6 address, then the first IPv4 endpoint should be moved up in the list to be second in the list. An implementation MAY choose to favor one address family more by allowing multiple addresses of that family to be attempted before trying the next. The number of contiguous endpoints of the first address family of properties will be referred to as the "Preferred Address Family Count" and can be a configurable value. This avoids waiting through a long list of endpoints for a given address family if connectivity over that address family is impaired.¶
Note that the endpoint selection described in this section only applies to destination addresses; Source Address Selection ([RFC6724-UPDATE], Section 3.2) is performed once per destination address and is out of scope of this document.¶
Once the list of endpoints received up to this point has been constructed, the client will attempt to make connections. In order to avoid unreasonable network load, connection attempts SHOULD NOT be made simultaneously. Instead, one connection attempt to a single endpoint is started first, followed by the others, one at a time. Starting a new connection attempt does not affect previous attempts, as multiple connection attempts may occur in parallel. Once one of the connection attempts succeeds (Section 6.1), all other connection attempts that have not yet succeeded SHOULD be canceled. Any endpoint that was not yet attempted as a connection SHOULD be ignored. At that time, any asynchronous DNS queries MAY be canceled as new endpoints will not be used for this connection. However, the DNS client resolver SHOULD still process DNS replies from the network for a short period of time (recommended to be 1 second), as they will populate the DNS cache and can be used for subsequent connections.¶
Cancelling remaining in-flight attempts once a connection succeeds avoids unnecessary load on the network and server. In addition, if an earlier, more preferred attempt (such as QUIC or IPv6) did not complete before a later fallback attempt (such as TLS over TCP or IPv4) succeeded, that path might be experiencing packet loss, rate limiting, or other impairments, so switching to it can degrade performance. However, client implementations with additional context (for example, an HTTP connection manager that prefers HTTP/3 over HTTP/2 for subsequent requests) MAY allow an already in-flight, more preferred attempt to continue in the background rather than cancelling it immediately, taking care to evaluate path quality before preferring that connection and to close redundant connections when no longer needed. Specific mechanisms for managing connection pools or switching between established connections are out of scope for this document.¶
Each connection attempt represents an independent transport connection with its own connection identifiers and cryptographic handshake state (for example, separate TCP connections or separate QUIC connections), so handshake packets cannot be reused between attempts. When TLS is used (either over TCP or as part of QUIC), clients MUST NOT reuse key shares across connection attempts (Section 4.2.8 of [RFC9846]). Similarly, when attempting multiple QUIC connections (such as over IPv6 and IPv4), clients MUST NOT send copies of the same QUIC Initial packet or reuse Connection IDs across attempts (Section 9.5 of [QUIC]). Avoiding reuse of Connection IDs and cryptographic handshake values prevents observers from correlating the client's addresses across network paths. Because attempts are separated by the Connection Attempt Delay, most connections complete on the first attempt without incurring the cost of additional handshakes.¶
If grouping endpoints by application or security requirements (Section 5.1) produced multiple groups, the application SHOULD start with connection attempts to the most preferred option. The policy for attempting any endpoints outside of the most preferred group is up to the client implementation and out of scope for this document.¶
If grouping endpoints by service (Section 5.2) produced multiple groups, all of the endpoints of the first group SHOULD be started before starting attempts using the next group. Attempts across service groups SHOULD be allowed to continue in parallel; in effect, the groups are flattened into a single list. The intent of these groups is to strictly prioritize the most preferred service. Therefore, if a higher priority group has many endpoints, there is a potential for long delays before falling back to lower priority groups.¶
A simple implementation can have a fixed delay for how long to wait before starting the next connection attempt. This delay is referred to as the "Connection Attempt Delay". One recommended value for a default delay is 250 milliseconds. A more nuanced implementation's delay should correspond to the time when the previous attempt is retrying its handshake (such as sending a second TCP SYN or a second QUIC Initial), based on the retransmission timer ([RFC6298], [RFC9002]). If the client has historical RTT data gathered from other connections to the same host or prefix, it can use this information to influence its delay. Transport retransmission timers are generally tuned so that most healthy connections complete their initial handshake without retransmitting; waiting until roughly the first handshake retransmission gives the preferred attempt a fair chance to succeed without starting redundant connection attempts in the common case, while starting the next attempt promptly once the initial packet (or its response) is likely to have been lost.¶
Note that this algorithm should only try to approximate the time of the first handshake packet retransmission, and not any further retransmissions that may be influenced by exponential timer back off. In practice, the layer implementing Happy Eyeballs often operates above the transport layer and might not directly control or know the exact timing of transport-layer retransmissions. Even when retransmission timing is known or closely estimated, sending a handshake retransmission on a previous attempt at the same time as the initial packet of a new attempt can create a small burst of packets when the network is already experiencing loss. Implementations MAY apply a small amount of jitter or pacing to avoid sending both packets simultaneously.¶
Clients that support session resumption mechanisms (such as TLS session tickets [RFC8446] or QUIC 0-RTT [RFC9001]) SHOULD use the same Connection Attempt Delay for resumed connections as for new connections.¶
The Connection Attempt Delay MUST have a lower bound, especially if it is computed using historical data. More specifically, a subsequent connection MUST NOT be started within 10 milliseconds of the previous attempt. The recommended minimum value is 100 milliseconds, which is referred to as the "Minimum Connection Attempt Delay". This minimum value is required to avoid congestion collapse in the presence of high packet-loss rates. The Connection Attempt Delay SHOULD have an upper bound, referred to as the "Maximum Connection Attempt Delay". The current recommended value is 2 seconds.¶
An implementation MAY increase the Connection Attempt Delay for each additional connection attempt that is started while earlier attempts are still in progress, multiplying the delay by a fixed factor (the "Connection Attempt Delay Multiplier") for each such attempt. The multiplier scales whichever base delay the implementation uses: the RTT-derived estimate described above when RTT data is available, or the fixed default otherwise. A short base delay starts a first fallback quickly, while the multiplier spaces out later attempts so the aggregate attempt rate stays low. For example, with a fixed base delay of 50 milliseconds and a multiplier of 2, attempts are started at 0, 50, 150, 350, and 750 milliseconds. A multiplier of 1 keeps the delay constant. A base delay below the recommended Minimum Connection Attempt Delay MAY be used (for example, with a multiplier greater than 1), but the 10 millisecond hard lower-bound still applies.¶
The Connection Attempt Delay is used to set a timer, referred to as the "Next Connection Attempt Timer". Whenever this timer fires and a connection has not been successfully established, the next connection attempt starts, and the timer either is reset to a new delay value or, in the case of the end of the list being reached, is cancelled. Note that the delay value can be different for each connection attempt (depending on the protocol being used and the estimated RTT).¶
The algorithm in this document describes establishing a single connection, and the Connection Attempt Delay bounds the attempt rate of a single Happy Eyeballs procedure. However, an application might initiate multiple concurrent connection requests to the same host or service within a short period (for example, for parallel HTTP/1.1 requests, or when a speculative preconnect is followed closely by an active request). Running uncoordinated Happy Eyeballs procedures in parallel can still produce an aggregate burst of connection attempts to the same destination. While mechanisms for managing pools of multiple connections are out of scope for this document, client implementations can mitigate such bursts by coalescing resolution and in-flight connection establishment when a single connection can be shared (such as with HTTP/2 or HTTP/3), or by coordinating attempt pacing across concurrent Happy Eyeballs procedures targeting the same host or service when multiple connections are needed.¶
The determination of when a connection attempt has successfully completed (and other attempts can be cancelled) ultimately depends on the client application's interpretation of the connection state being ready to use. This will generally include at least the transport-level handshake with the remote endpoint (such as the TCP or QUIC handshake), but can involve other higher-level handshakes or state checks as well.¶
Client connections that use TCP only (without TLS or another protocol on top, such as for unencrypted HTTP connections) will determine successful establishment based on completing the TCP handshake only. When TLS is used on top of TCP (such as for encrypted HTTP connections), clients SHOULD wait for the TLS handshake to successfully complete before cancelling other connection attempts. This is particularly useful for networks in which a TCP-terminating proxy might be causing TCP handshakes to succeed quickly, even though end-to-end connectivity with the TLS-terminating server will fail. QUIC connections inherently include a secure handshake in their main handshakes, and thus usually only need to wait for a single handshake to complete.¶
Beyond TCP, TLS, and/or QUIC handshakes, clients may also wait for other requirements to be met before determining that the connection establishment was successful. For example, clients generally validate that the server's certificate provided via TLS is trusted, and that operation can be asynchronous.¶
In cases where the connection establishment determination goes beyond the initial transport handshake, the Next Connection Attempt Timer ought to be adjusted after the initial transport handshake is completed. When the connection establishment makes progress, but has not completed, the timer SHOULD be extended to a new value that represents an estimated time for the full connection establishment to complete.¶
For example, consider a case where connection establishment involves both a TCP handshake and a TLS handshake. If the timer is initially set to be roughly at the time when a TCP SYN packet would be retransmitted, and the TCP handshake completes before the timer fires, the timer should be adjusted to allow for the time in which the TLS handshake could complete.¶
While transport layer handshakes generally do not have restrictions on attempts to establish a connection, some cryptographic handshakes might depend on SVCB ServiceMode records and impose limitations on establishing a connection. For instance, ECH-capable clients might rely on SVCB records that contain the "ech" SvcParamKey [SVCB-ECH] before starting a TLS handshake. See Section 6.3 for details on when clients need to pend or abandon connection attempts while awaiting SVCB records.¶
The alpn and no-default-alpn SvcParamKeys in SVCB records indicate the
"SVCB ALPN set," which specifies the underlying transport protocols
supported by the associated service endpoint. When the client requests
SVCB records, it SHOULD perform the procedure specified in Section 7.1.2 of [SVCB] to determine the underlying transport protocols that both
the client and the service endpoint support. The client SHOULD NOT
attempt to make a connection to a service endpoint whose SVCB ALPN set
does not contain any protocols that the client supports. For example,
suppose the client is an HTTP client that only supports TCP-based
versions such as HTTP/1.1 and HTTP/2, and it receives the following
HTTPS record:¶
example.com. 60 IN HTTPS 1 svc1.example.com. (
alpn="h3" no-default-alpn ipv6hint=2001:db8::2 )
¶
In this case, attempting a connection to 2001:db8::2 or any other
address resolved for svc1.example.com would be incorrect because the
record indicates that svc1.example.com only supports HTTP/3, based on
the ALPN value of "h3".¶
If the client is an HTTP client that supports both Alt-Svc [AltSvc] and SVCB (HTTPS) records, the client SHOULD ensure that connection attempts are consistent with both the Alt-Svc parameters and the SVCB ALPN set, as specified in Section 9.3 of [SVCB].¶
Some situations related to handling SVCB responses can require connection attempts to be dropped, or pended until SVCB responses return.¶
Section 3.1 of [SVCB] describes client behavior for handling resolution failures when responses are "cryptographically protected" using DNSSEC [DNSSEC] or encrypted DNS ([DOT], [DOH], or [DOQ], for example). If SVCB resolution fails when using cryptographic protection, clients SHOULD abandon connection attempts altogether to avoid downgrade attacks.¶
Use of cryptographic protection in DNS can influence other parts of Happy Eyeballs connection establishment, as well.¶
Situations in which DNS is not protected allow for any records to be blocked or modified, so security properties derived from SVCB records are opportunistic only. However, when DNS is cryptographically protected, clients can be stricter about relying on the properties from SVCB records.¶
Section 5.1 of [SVCB] explains that clients "MUST NOT transmit any information that could be altered by the SVCB response until it arrives", and specifically mentions properties that affect the TLS ClientHello. This restriction specifically applies when a client's behavior will be altered by the SVCB response, which depends both on the client implementation's ability to support a particular feature, as well as the client implementation's willingness to rely on the SVCB response to enable a particular feature.¶
Based on this, clients in some scenarios MUST pend starting a TLS handshake (either after TCP or as part of QUIC) until SVCB responses have been received, even after the "Resolution Delay" defined in Section 4 has been reached. Specifically, clients MUST pend starting handshakes if all of the following are true:¶
DNS responses are cryptographically protected with DNSSEC or encrypted DNS. Note that, if unencrypted and unsigned DNS is used, SVCB information is opportunistic; clients MAY wait for SVCB responses but do not need to.¶
The client implementation supports parsing and using a particular security-related SVCB parameter, such as the "ech" SvcParamKey [SVCB-ECH]. (In contrast, implementations that do not support actively using ECH do not need to wait for SVCB resolution if that is the only reason to do so).¶
The client relies on the presence of the particular
SVCB-related parameter to enable the relevant protocol feature.
For example, if a connection attempt would normally be
using cleartext HTTP unless an HTTPS DNS record would
cause the client to upgrade, the client needs to
wait for the record; however, if the client already
would be using HTTP over TLS, then it is not relying
on that signal from SVCB. As another example, some SVCB
properties can affect the TLS ClientHello in ways that optimize
performance (like tls-supported-groups [I-D.ietf-tls-key-share-prediction])
but only aim to save round trips. The other TLS groups
can be discovered through the TLS handshake itself, instead
of SVCB, and thus do not require waiting for SVCB responses.¶
Pending the TLS handshake affects transport protocols differently once address records are available and any applicable Resolution Delay has elapsed:¶
For QUIC, the TLS ClientHello is carried in the initial packet of the connection. If the client needs to pend starting the TLS handshake until SVCB responses have arrived, it needs to pend sending any QUIC packets.¶
When TLS is used over TCP and the client needs to pend starting the TLS handshake, the client MAY speculatively start the TCP handshake using resolved A or AAAA addresses while holding back the TLS ClientHello until SVCB responses arrive. If the SVCB responses allow using an endpoint for which a speculative TCP handshake was started (for example, when SVCB returns a negative response or a ServiceMode record with TargetName "."), the client can proceed with the TLS handshake on that TCP connection. Conversely, if an endpoint with an in-progress or completed speculative TCP handshake is not selected once the SVCB response arrives (for example, because the client selects an alternative TargetName that provides "ech" [SVCB-ECH]), the client SHOULD close that TCP connection without sending a TLS ClientHello.¶
Starting a speculative TCP handshake before SVCB resolution completes trades privacy for reduced latency: although the TLS ClientHello is not exposed, sending TCP SYN packets to the origin's addresses can reveal communication with IP addresses that the client would not have contacted if an SVCB record directed it to an alternative TargetName (such as a shared ECH-enabled frontend). Clients with stricter privacy requirements MAY pend the TCP handshake until SVCB responses have been received.¶
If, during the course of connection establishment, the DNS answers change by either adding resolved endpoints (for example due to DNS push notifications [RFC8765]) or removing previously resolved endpoints (for example, due to expiry of the TTL on that DNS record), the client should react based on its current progress. Additionally, endpoints from SVCB IP hints SHOULD be removed from the list once A and AAAA records are received for the corresponding name, if the endpoints from the hints are absent from the received records Section 7.3 of [SVCB].¶
If an endpoint is removed from the list that already had a connection attempt started, the connection attempt SHOULD NOT be canceled, but rather be allowed to continue. If the removed endpoint had not yet had a connection attempt started, it SHOULD be removed from the list of endpoints to try.¶
If an endpoint is added to the list, its position SHOULD be determined by applying the sorting rules (see Section 5) to the complete list of endpoints, including those previously received. This ensures that sorting rules, such as address family interleaving, are maintained correctly regardless of when endpoints arrive. For example, consider a connection attempt in which only IPv6 addresses are available initially, and an attempt to one IPv6 address endpoint is already in progress. Then, when IPv4 addresses are later received, an IPv4 address endpoint should be placed next in the list of endpoints to attempt (to account for interleaving address families) ahead of any remaining IPv6 address endpoints, as if it had been available initially.¶
When DNS answers change while a Connection Attempt Delay timer is running, the client MAY reschedule the timer. While a DNS update alone does not justify rescheduling the timer, if at least one connection attempt started before the DNS update has not made progress within an expected time window, the client MAY treat this as a signal that the previous addresses may no longer be viable and fire the timer sooner to start a connection attempt to the next address in the updated list, subject to the Minimum Connection Attempt Delay.¶
NAT64 [NAT64] is an IPv6 transition protocol that allows clients with IPv6-only connectivity to access IPv4-only peers outside the local link. When NAT64 is in use, an IPv6 prefix, referred to as PREF64, is used on by the NAT for synthesizing IPv4 addresses into IPv6 addresses.¶
Clients can discover a network's PREF64 in one of the following ways:¶
If a network with IPv6-only connectivity does not provide the prefix in a Router Advertisement [PREF64], clients SHOULD send the DNS query to discover the prefix [RFC7050].¶
Networks that use NAT64 might also include DNS64 [DNS64], in which the DNS resolver synthesizes A answers into AAAA answers. However, with the prefix available from router advertisements [PREF64], networks might choose to not deploy DNS64, as the latter has a number of disadvantages (see Section 4.3.4 of [V6-MOSTLY]).¶
To ensure compatibility with any NAT64 network, whenever the client detects a NAT64 prefix, from either of the options reference above, clients MUST send A queries in addition to AAAA queries (as specified in Section 4.1). This allows the client to receive any existing IPv4 A records and perform local NAT64 address synthesis, eliminating the network's need to run DNS64.¶
Synthesized IPv6 addresses (IPv4 addresses that have been synthensized into IPv6 addresses either locally using PREF64 or by a DNS64 resolver) MUST be de-synthesized into IPv4 addresses before being used by the Happy Eyeballs client for grouping and sorting (Section 5), and connecting. These addresses might be re-synthesized into IPv6 addresses (see Section 8.3), in which case implementations can choose to optimize processing by storing the original address, but still using the IPv4 address for purposes of sorting and route lookups.¶
IPv6 addresses received from AAAA records might come from DNS64 [DNS64]. Clients that are aware of the PREF64 value MUST check to see if an IPv6 address received from DNS is actually an IPv4 address.¶
When a client has discovered PREF64, it can use the prefix to synthesize IPv4 addresses into IPv6 addresses as defined in [RFC6052].¶
If the Happy Eyeballs client is attempting a connection to an IPv4 address when there is no IPv4 route that applies for that address, then the client MUST synthesize this address into an IPv6 address using the PREF64. These IPv4 addresses can come from DNS (via A records or IPv4 address hints received in SVCB/HTTPS records), or from de-synthesizing IPv6 addresses, or from IPv4 literal addresses passed by an application. This solution is similar to "Bump-in-the-Host" [RFC6535], but is implemented inside the Happy Eyeballs client.¶
Note that NAT64 address synthesis is not always required or possible. Some IPv4 prefixes are scoped to a given host or network and do not require synthesis, such as 0.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, and 255.255.255.255/32.¶
The Happy Eyeballs algorithm as described in this document applies to how resolution, sorting, and connection establishment are performed on a single network configuration. For the purposes of this document, the definition of a Provisioning Domain (PvD) [PvD] is used to refer to this network configuration. A PvD is defined as "a consistent set of network configuration information", including the DNS servers and router prefixes assigned by the network connection.¶
Multiple PvDs can be in use over time for various reasons: a client device's network configuration or attachments might change (joining or leaving a Wi-Fi network, connecting to a wired Ethernet network, establishing a tunnel to a VPN server), and a client device can be attached to multiple networks at the same time (such as a mobile device having connectivity to both a Wi-Fi network and a cellular network).¶
Clients implementing the Happy Eyeballs algorithm MUST partition the information used to guide the algorithm across different PvDs. Specifically, the following properties cannot be used across different PvDs:¶
DNS answers (even when PvDs share a configured DNS resolver, as answers can depend on the network path)¶
Historical data used to sort endpoints, such as round trip times and previously used addresses (see Section 5.3), or to compute the Connection Attempt Delay (see Section 6)¶
Information that is cached per-PvD, such as historical round trip data and DNS answers, SHOULD be flushed whenever a device changes the PvD to which it is attached. However, if a client can reliably identify a previously attached PvD, it MAY retain and resume using cached data associated with that PvD upon reconnection.¶
VPNs (Virtual Private Networks) can pose specific complexities, particularly when they have split-horizon DNS configurations (see [RFC9704] for a definition of split-horizon DNS). For example, a VPN configuration might require that all queries for names under "example.com" be sent to a VPN-specific DNS server, and address answers from that DNS server might end up being routed either over the VPN tunnel or over a non-VPN route. The requirement above to partition information across PvDs does not mean that split-horizon VPNs will lead to failures. Instead, the set of split-horizon DNS servers and routes ought to be considered as one larger PvD. When a VPN is connected or disconnected (adding or removing a split-horizon configuration), the client ought to consider that to be a PvD change and flush or re-fetch cached state such as DNS answers.¶
The values that may be configured as defaults on a client for use in Happy Eyeballs are as follows:¶
Resolution Delay (Section 4): The time to wait for AAAA and/or SVCB/HTTPS records after receiving an A record. Recommended to be 25 milliseconds.¶
Preferred Address Family Count (Section 5): The number of endpoints belonging to the preferred address family (such as IPv6) that should be attempted before attempting the next address family. Recommended to be 1; 2 may be used to more aggressively favor a particular combination of address family and protocol.¶
Connection Attempt Delay (Section 6): The time to wait between connection attempts in the absence of RTT data. Recommended to be 250 milliseconds.¶
Minimum Connection Attempt Delay (Section 6): The minimum time to wait between connection attempts. Recommended to be 100 milliseconds. MUST NOT be less than 10 milliseconds.¶
Maximum Connection Attempt Delay (Section 6): The maximum time to wait between connection attempts. Recommended to be 2 seconds.¶
Connection Attempt Delay Multiplier (Section 6): An optional factor by which the Connection Attempt Delay is multiplied for each additional concurrent connection attempt in progress. Recommended to be 1 (a constant delay); values greater than 1 grow the delay per attempt and allow a shorter base delay.¶
The delay values described in this section were determined empirically by measuring the timing of connections on a very wide set of production devices. They were picked to reduce wait times noticed by users while minimizing load on the network. As time passes, it is expected that the properties of networks will evolve. For that reason, it is expected that the values chosen by implementations will change over time. Implementors MAY use values different from the recommended values listed above, without changing this specification, as long as they do not violate any of the normative requirements (such as minimum delays).¶
Happy Eyeballs will handle initial connection failures at the transport layer (such as TCP or QUIC); however, other failures or performance issues may still affect the chosen connection.¶
Connections that use TCP only (without TLS or another protocol on top) perform connection racing only during the TCP handshake. Such connections can encounter issues where the TCP handshake (using small packets) completes but then large packets are dropped or incorrectly handled by the network due to a small MTU being configured somewhere in the network. Such issues might be more likely with IPv6 traffic [RFC8900] due to the network being unable to fragment IPv6 packets and associated issues with Path MTU Discovery, such as with ICMPv6 PTB messages not making it back to the client.¶
This problem can also occur when TLS is used, but the larger messages used in many TLS handshakes are often sufficient to ensure maximum-size TCP segments are deliverable. For QUIC connections, a minimum MTU of at least 1200 bytes [RFC9000], Section 8.1-5 is guaranteed, but there is a chance that larger values may not be available.¶
Solving these issues is out of scope of this document. One suggested approach is to use "Packetization Layer Path MTU Discovery" [RFC4821].¶
If the DNS returns multiple endpoints for different application servers, the application itself may not be operational and functional on all of them. Common examples include Transport Layer Security (TLS) and HTTP.¶
It has been observed in practice that Happy Eyeballs can hide issues in networks. For example, if a misconfiguration causes IPv6 to consistently fail on a given network while IPv4 is still functional, Happy Eyeballs may impair the operator's ability to notice the issue. It is recommended that network operators deploy external means of monitoring to ensure functionality of all address families.¶
Note that applications should not rely upon a stable hostname-to-address mapping to ensure any security properties, since DNS results may change between queries. Happy Eyeballs may make it more likely that subsequent connections to a single hostname use different IP addresses.¶
When using HTTP, HTTPS resource records indicate that clients should require HTTPS when connecting to an origin (see Section 9.5 of [SVCB]), so an active attacker can attempt a downgrade attack by interfering with the successful delivery of HTTPS resource records. When clients use insecure DNS mechanisms, any on-path attacker can simply drop HTTPS resource records, so clients cannot tell the difference between an attack and a resolver that fails to respond to HTTPS queries.¶
However, when using cryptographically protected DNS mechanisms, as described in Section 3.1 of [SVCB], both SVCB-reliant and SVCB-optional clients MUST NOT send any unencrypted data after the TCP handshake completes unless they have received a valid HTTPS response. Those clients need to complete a TLS handshake before proceeding if that response is non-negative.¶
Similar downgrade considerations apply to security-related SVCB parameters such as "ech" [SVCB-ECH], which provides ECH configurations [ECH] used to encrypt sensitive fields of the TLS ClientHello. Even when DNS queries use an encrypted transport, an on-path attacker might attempt to selectively delay or drop packets carrying SVCB or HTTPS responses (for example, using packet timing or size heuristics) while allowing A and AAAA responses through. If an ECH-capable client proceeded with an unencrypted TLS ClientHello after the Resolution Delay without waiting for the SVCB or HTTPS response, the attacker could force ECH to be omitted. Waiting for SVCB or HTTPS responses before starting the TLS handshake when DNS is cryptographically protected, and abandoning connection attempts if protected resolution fails (see Section 6.3), prevents this downgrade attack.¶
Additionally, as described in Section 6.3, speculatively starting a TCP handshake using A or AAAA records before SVCB or HTTPS resolution completes does not expose the TLS ClientHello, but can still expose traffic to origin IP addresses that would not have been contacted if an SVCB or HTTPS record directed the client to an alternative TargetName (such as a shared ECH-enabled frontend). Clients with stricter privacy requirements can avoid this exposure by waiting for SVCB or HTTPS responses before starting the TCP handshake.¶
This document does not require any IANA actions.¶
The authors thank Dan Wing, Andrew Yourtchenko, and everyone else who worked on the original Happy Eyeballs design [RFC6555], Josh Graessley, Stuart Cheshire, and the rest of team at Apple that helped implement and instrument this algorithm, and Jason Fesler and Paul Saab who helped measure and refine this algorithm. The authors would also like to thank Fred Baker, Nick Chettle, Lorenzo Colitti, Igor Gashinsky, Geoff Huston, Jen Linkova, Paul Hoffman, Philip Homburg, Warren Kumari, Erik Nygren, Jordi Palet Martinez, Rui Paulo, Stephen Strowes, Jinmei Tatuya, Dave Thaler, Joe Touch, James Woodyatt, Ondřej Caletka, Philipp Tiesel, and Max Inden for their input and contributions.¶