Hello, getting an error in TLS connections in nix build sandbox. Not reproducible outside nix sandbox.
[justin@zenbox ~]$ nix-shell -p terraform
these 3 derivations will be built:
/nix/store/nnpa7v6356kp9pgmqp3dqfa48xf599k0-source.drv
/nix/store/6r007ljlv22zdgls4n9gyd566ppbpkkd-terraform-1.15.3-go-modules.drv
/nix/store/c1acnmh5i8sm7bmd0y16qxv91x7y84va-terraform-1.15.3.drv
building '/nix/store/nnpa7v6356kp9pgmqp3dqfa48xf599k0-source.drv'...
structuredAttrs is enabled
trying https://github.com/hashicorp/terraform/archive/v1.15.3.tar.gz
curl: (35) TLS connect error: error:0A000410:SSL routines::ssl/tls alert handshake failure
Warning: Problem (retrying all errors). Retrying in 1 second. 3 retries left.
curl: (35) TLS connect error: error:0A000410:SSL routines::ssl/tls alert handshake failure
Warning: Problem (retrying all errors). Retrying in 2 seconds. 2 retries left.
curl: (35) TLS connect error: error:0A000410:SSL routines::ssl/tls alert handshake failure
Warning: Problem (retrying all errors). Retrying in 4 seconds. 1 retry left.
But non-sandboxed connection succeeds:
[justin@zenbox ~]$ curl https://github.com/hashicorp/terraform/archive/v1.15.3.tar.gz -L -o /dev/null | tail
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 0
100 5.50M 100 5.50M 0 0 1.32M 0 00:04 00:04 1.05M
[justin@zenbox ~]$ echo $?
0
So this is not a networking issue but something broader.
Happens with many packages, but seems to happen with github urls. Is this just github being flaky (as usual) or a nix bug?
Nope. Leaning toward it not being a nix bug, but a server side bug on github infrastructure (the fastly cdn) not handling X25519MLKEM768 key exchange properly.
Commented human readable tshark output:
# Connection: CLIENT.<sport> β 140.82.112.4:443 (github.com via Fastly)
# Captured: 2026-06-02 09:25:23 β 09:25:27 UTC (β4.6 s)
# Trigger: nix-prefetch-url 'https://github.com/hashicorp/terraform/archive/v1.15.3.tar.gz'
# Toolchain: nix 2.34.7 β libcurl 8.20.0 + OpenSSL 3.6.2 + ngtcp2 1.22.1
# Note: No UDP/443 (HTTP/3) traffic observed. Plain TCP/TLS.
23.141395 CLIENT β server SYN
23.267708 CLIENT β server SYN/ACK (MSS 1436)
23.267720 CLIENT β server ACK
# --- TLS ClientHello (1554-byte TLS record, split across 2 TCP segments) ---
23.268408 CLIENT β server [.] len 1424 # ClientHello part 1
23.268411 CLIENT β server [P.] len 135 # ClientHello part 2
# TLS record: type=22 (handshake), legacy_version=0x0301, length=0x0612 (1554 bytes)
# handshake: type=0x01 (ClientHello), length=1550
# SNI: "github.com"
# ALPN: h2, http/1.1
# key_share extension (type 0x0033, length 1258):
# - group 0x11ec = X25519MLKEM768 (post-quantum hybrid, ~1216-byte pubkey)
# - group 0x001d = x25519
# - group 0x0017 = secp256r1
# - group 0x001e = x448
# - group 0x0018 = secp384r1
# - group 0x0019 = secp521r1
# supported_versions: TLS 1.3 (and 1.2)
# signature_algorithms: standard set
# --- Server handshake response (multi-segment) ---
23.370288 CLIENT β server [.] len 1424 # ServerHello + EncryptedExtensions
23.370295 CLIENT β server [P.] len 1424 # Certificate (part 1)
23.370299 CLIENT β server [P.] len 250 # Certificate (part 2), CertVerify, Finished
# Server accepts the ClientHello β no alert, no HelloRetryRequest.
# This edge node supports X25519MLKEM768.
# --- TLS handshake completes; client Finished + HTTP request #1 ---
23.371762 CLIENT β server [P.] len 64 # Client Finished (encrypted)
23.371833 CLIENT β server [P.] len 182 # HTTP request #1 (encrypted)
23.387179 CLIENT β server [P.] len 48 # (small client app-data record)
23.391463 CLIENT β server [P.] len 79 # NewSessionTicket
23.391470 CLIENT β server [P.] len 79 # NewSessionTicket
23.391472 CLIENT β server [P.] len 64 # (control record)
23.406372 CLIENT β server [P.] len 31 # (control record)
# --- HTTP response #1 (~4 KB) ---
23.515591 CLIENT β server [.] len 1424
23.515595 CLIENT β server [.] len 1424
23.515600 CLIENT β server [P.] len 1284
# --- HTTP request/response #2 (~290 ms later β first retry, matches
# nix-prefetch-url backoff "retrying in 345 ms") ---
23.900467 CLIENT β server [P.] len 70 # HTTP request #2
23.920260 CLIENT β server [P.] len 48
23.926723 CLIENT β server [.] len 1424
23.926732 CLIENT β server [.] len 1424
23.926737 CLIENT β server [P.] len 1284
# --- HTTP request/response #3 (~580 ms later β "retrying in 555 ms") ---
24.498866 CLIENT β server [P.] len 70
24.518621 CLIENT β server [P.] len 48
24.526415 CLIENT β server [.] len 1424
24.526420 CLIENT β server [.] len 1424
24.526424 CLIENT β server [P.] len 1284
# --- HTTP request/response #4 (~1.07 s later β "retrying in 1040 ms") ---
25.592314 CLIENT β server [P.] len 70
25.612074 CLIENT β server [P.] len 48
25.617233 CLIENT β server [.] len 1424
25.617237 CLIENT β server [.] len 1424
25.617241 CLIENT β server [P.] len 1284
# --- HTTP request/response #5 (~2.13 s later β "retrying in 2109 ms") ---
27.745408 CLIENT β server [P.] len 70
27.770281 CLIENT β server [P.] len 48
27.771657 CLIENT β server [.] len 1424
27.771662 CLIENT β server [.] len 1424
27.771666 CLIENT β server [P.] len 1284
# --- Connection teardown ---
27.790707 CLIENT β server [P.] len 48 # close_notify
27.790826 CLIENT β server [FP.] len 24 # FIN + close_notify
27.811809 CLIENT β server [P.] len 24 # close_notify
27.811814 CLIENT β server [R] # RST (curl tearing down)
27.811816 CLIENT β server [F.] # server FIN
27.811819 CLIENT β server [R] # RST
I was totally wrong. For anyone coming accross this, this was a problem on my end and not with Nix or Github.
I had configured a search domain for my local network with a wildcard.
Because github doesnβt have ipv6, and curl in nix daemon prefers ipv6, it will try querying the AAAA record. When it doesnβt exist, it used my search domain for my network, which had a wildcard entry *.domain.com. This resolved to a valid cloudflare server which causes the SSL error.
Fix was at the network level to disable both the domain_name and domain_search options on my dhcp server.
In case you want to reproduce this outside of a nix build, stop nscd.service.
The reason why this changes anything is a combination of two factors
- glibc will try domains in the search list on a no data response (domain exists but no data of the specified type (AAAA) was found)
- curl will use getaddrinfo to lookup IPv4 and IPv6 addresses individually, nscd and nsncd will lookup addresses of any protocol.
This means that if nscd is used (i.e. outside the nix build) the address search will continue until either an IPv4 or IPv6 address is found (both can be found for the same domain). Whereas if nscd is not used, the address search will continue until either both an IPv4 and IPv6 address are found or all the search domains are exhausted.
1 Like