When the configured S3 substituter URL specifies profile=<name> and that profile is an AWS SSO profile (sso_session / sso_start_url / sso_region etc.), the nix-daemon process crashes with Nix daemon disconnected unexpectedly (maybe it crashed?).
The crash is triggered solely by the shape of the profile — no valid SSO session, no cached SSO token, no real AWS account, and no real S3 bucket are required to reproduce. Pointing the substituter at a bogus bucket name is sufficient.
A profile with static credentials (aws_access_key_id / aws_secret_access_key) under the same conditions does not crash.
Origin
git bisect pinpointed the bug at commit ec91479 ("libstore: add AWS SSO support for S3 authentication"; originally tagged in 2.34.0). The prior commit (a6eb2e9) does not show the bug. I'm unclear if the bug reproduces on master ( #ff05a94aa) - something else seemed to be blocking the ability to start the daemon.
Steps To Reproduce
-
Add the following to ~/.aws/config (no ~/.aws/credentials changes
required):
[profile brokennix]
sso_session = brokennix-sso
sso_account_id = 123456789012
sso_role_name = FakeRole
region = us-east-2
[sso-session brokennix-sso]
sso_start_url = https://fake.awsapps.com/start
sso_region = us-east-2
sso_registration_scopes = sso:account:access
[profile workingnix]
aws_access_key_id = nixadmin
aws_secret_access_key = nixadmin-secret-123
Note: the SSO profile points at a nonexistent endpoint
(https://fake.awsapps.com/start) and uses a fake account id and role.
No cached SSO token under ~/.aws/sso/cache/ is required.
-
Run nix-store --realise against a bogus store path, with the substituter
pointed at the SSO profile:
sub='s3://baz?profile=brokennix'
nix-store -vvvv \
--realise "/nix/store/00000000000000000000000000000000-nonexistent" \
--option substituters "$sub" \
--option trusted-substituters "$sub"
-
Observed: the daemon (worker) crashes:
…
(aws:channel) id=0x…: creating new slot 0x…
(aws:socket-handler) id=0x…: Socket handler created with max_read_size of 16384
(aws:socket) id=0x… fd=39: subscribing to readable events
(aws:channel-bootstrap) id=0x…: Setting up socket handler on channel 0x… with handler 0x… on slot 0x…
(aws:channel) id=0x…: creating new slot 0x…
closing daemon connection because of an exception
error: Nix daemon disconnected unexpectedly (maybe it crashed?)
-
Run the same command, swapping in the static-credentials profile:
sub='s3://baz?profile=workingnix'
nix-store -vvvv \
--realise "/nix/store/00000000000000000000000000000000-nonexistent" \
--option substituters "$sub" \
--option trusted-substituters "$sub"
Observed: the daemon survives and the command fails cleanly with the
expected diagnostic:
error: path '/nix/store/00000000000000000000000000000000-nonexistent' is required, but there is no substituter that can build it
Expected behavior
The daemon should not crash. With an SSO-shaped profile whose preconditions
are not satisfied (no cached token, unreachable SSO endpoint, etc.), the AWS
SDK's SSO credential provider is expected to either:
- fail gracefully and skip itself in the provider chain (matching the behavior
observed with a malformed/missing profile section), or
- surface a normal error such as "could not resolve credentials" that nix
reports without terminating the daemon.
Either way, behavior should mirror the static-credentials path: the build
should fail with no substituter that can build it, without taking the daemon
down.
Metadata
- Platform: macOS 26.3.1 (Tahoe), arm64 (Apple Silicon)
Additional context
- The trigger appears to be the AWS SDK's SSO credential provider being added
to the chain (logged as Added AWS SSO Credential Provider to chain for profile '<name>') and proceeding through TLS channel setup. Static-key
profiles never open a TLS connection during credential resolution and thus
never hit the broken CF/Security state.
- Static-credential profiles, including profiles with empty/missing credential
fields, do not exhibit the crash — only profiles whose configuration shape
causes the SDK to instantiate the SSO provider (and thus call
SSLCreateContext from a forked-without-exec child) do.
- Only the forked worker crashes, not the listener daemon. The listener
itself remains alive and accepts new connections, but any subsequent
connection that triggers the same code path will fork a fresh worker that
also crashes.
- Running the equivalent operation against a local store (
--store local,
no daemon process) succeeds: TLS negotiation completes, credential
resolution fails cleanly with an authentication error, and the substituter
falls through normally.
Checklist
When the configured S3 substituter URL specifies
profile=<name>and that profile is an AWS SSO profile (sso_session/sso_start_url/sso_regionetc.), the nix-daemon process crashes withNix daemon disconnected unexpectedly (maybe it crashed?).The crash is triggered solely by the shape of the profile — no valid SSO session, no cached SSO token, no real AWS account, and no real S3 bucket are required to reproduce. Pointing the substituter at a bogus bucket name is sufficient.
A profile with static credentials (
aws_access_key_id/aws_secret_access_key) under the same conditions does not crash.Origin
git bisectpinpointed the bug at commit ec91479 ("libstore: add AWS SSO support for S3 authentication"; originally tagged in 2.34.0). The prior commit (a6eb2e9) does not show the bug. I'm unclear if the bug reproduces on master ( #ff05a94aa) - something else seemed to be blocking the ability to start the daemon.Steps To Reproduce
Add the following to
~/.aws/config(no~/.aws/credentialschangesrequired):
Note: the SSO profile points at a nonexistent endpoint
(
https://fake.awsapps.com/start) and uses a fake account id and role.No cached SSO token under
~/.aws/sso/cache/is required.Run
nix-store --realiseagainst a bogus store path, with the substituterpointed at the SSO profile:
Observed: the daemon (worker) crashes:
Run the same command, swapping in the static-credentials profile:
Observed: the daemon survives and the command fails cleanly with the
expected diagnostic:
Expected behavior
The daemon should not crash. With an SSO-shaped profile whose preconditions
are not satisfied (no cached token, unreachable SSO endpoint, etc.), the AWS
SDK's SSO credential provider is expected to either:
observed with a malformed/missing profile section), or
reports without terminating the daemon.
Either way, behavior should mirror the static-credentials path: the build
should fail with
no substituter that can build it, without taking the daemondown.
Metadata
Additional context
to the chain (logged as
Added AWS SSO Credential Provider to chain for profile '<name>') and proceeding through TLS channel setup. Static-keyprofiles never open a TLS connection during credential resolution and thus
never hit the broken CF/Security state.
fields, do not exhibit the crash — only profiles whose configuration shape
causes the SDK to instantiate the SSO provider (and thus call
SSLCreateContextfrom a forked-without-exec child) do.itself remains alive and accepts new connections, but any subsequent
connection that triggers the same code path will fork a fresh worker that
also crashes.
--store local,no daemon process) succeeds: TLS negotiation completes, credential
resolution fails cleanly with an authentication error, and the substituter
falls through normally.
Checklist