Disclosure: the analysis below was produced with AI assistance (Claude Code,
claude-opus-5).
Problem
On Windows the offline-degradation path in nix is unreachable, so nix never notices it is offline
and never applies the fallbacks it applies elsewhere.
haveInternet() (src/nix/main.cc:56) is implemented for POSIX and stubbed for Windows:
#else
// TODO implement on Windows
return true;
#endif
Its only consumer is src/nix/main.cc:560:
if (args.useNet && !haveInternet()) {
warn("you don't have Internet access; disabling some network-dependent features");
args.useNet = false;
}
Because the Windows arm returns true unconditionally, !haveInternet() is never true there, so the
body never runs and args.useNet is never cleared by this route.
Consequence
The block guarded by !args.useNet (main.cc:565-572) is what makes an offline nix behave sensibly:
if (!args.useNet) {
if (!settings.getWorkerSettings().useSubstitutes.overridden)
settings.getWorkerSettings().useSubstitutes = false;
if (!fetchSettings.tarballTtl.overridden)
fetchSettings.tarballTtl = std::numeric_limits<unsigned int>::max();
if (!fileTransferSettings.tries.overridden)
fileTransferSettings.tries = 0;
}
None of that engages on Windows. An offline Windows nix keeps consulting substituters, keeps treating
cached tarballs as expired, and keeps retrying transfers, instead of degrading and telling the user
why. Passing --no-net still works, so this is a missing automatic behavior rather than an inability
to work offline.
I am filing this as an issue rather than a patch because the TODO is deliberate and the fix is a
platform implementation question, not an oversight to correct in passing.
What implementing it would involve
The POSIX version walks getifaddrs() and looks for a non-loopback, non-link-local AF_INET or
AF_INET6 address, then falls back to haveNetworkProxyConnection(). The Windows equivalent is
GetAdaptersAddresses (iphlpapi), filtering the same way. IfOperStatusUp is available there and
would let the check be somewhat more precise than the POSIX one.
Relationship to #8216
#8216 asks for a way to override this check, because under krunvm only lo is exposed and
haveInternet() wrongly reports offline. That is the opposite failure, a false negative on Linux, but
it touches the same function, and an override switch would give Windows users a manual lever even
before the platform check exists.
Problem
On Windows the offline-degradation path in
nixis unreachable, sonixnever notices it is offlineand never applies the fallbacks it applies elsewhere.
haveInternet()(src/nix/main.cc:56) is implemented for POSIX and stubbed for Windows:Its only consumer is
src/nix/main.cc:560:Because the Windows arm returns
trueunconditionally,!haveInternet()is never true there, so thebody never runs and
args.useNetis never cleared by this route.Consequence
The block guarded by
!args.useNet(main.cc:565-572) is what makes an offlinenixbehave sensibly:None of that engages on Windows. An offline Windows
nixkeeps consulting substituters, keeps treatingcached tarballs as expired, and keeps retrying transfers, instead of degrading and telling the user
why. Passing
--no-netstill works, so this is a missing automatic behavior rather than an inabilityto work offline.
I am filing this as an issue rather than a patch because the
TODOis deliberate and the fix is aplatform implementation question, not an oversight to correct in passing.
What implementing it would involve
The POSIX version walks
getifaddrs()and looks for a non-loopback, non-link-localAF_INETorAF_INET6address, then falls back tohaveNetworkProxyConnection(). The Windows equivalent isGetAdaptersAddresses(iphlpapi), filtering the same way.IfOperStatusUpis available there andwould let the check be somewhat more precise than the POSIX one.
Relationship to #8216
#8216 asks for a way to override this check, because under krunvm only
lois exposed andhaveInternet()wrongly reports offline. That is the opposite failure, a false negative on Linux, butit touches the same function, and an override switch would give Windows users a manual lever even
before the platform check exists.