Skip to content

dotnet/sdk:10.0-alpine regression (sha256:620e765f...) — dotnet nuget/dotnet restore fail with EPERM on temp-file writes/renames anywhere in the container #7313

Description

@whighsmith

Describe the bug

Description

Between two floating-tag pulls of mcr.microsoft.com/dotnet/sdk:10.0-alpine roughly a week
apart, the image content changed in a way that breaks dotnet nuget add source and
dotnet restore inside our Docker builds. Every temp-file write/atomic-rename the SDK/NuGet
client performs fails with "Operation not permitted" (EPERM), regardless of directory.

  • Last known-good digest: sha256:d8ee39817ca03a3757288e83c37ed73cc969a286c603b827c7cbe33add1c2d1c
  • First known-bad digest: sha256:620e765fe18186c08399f7aa978f79f04b6bbf0ee1b3b8a91e2d5c9619e59da1

Repro

FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine
RUN dotnet nuget add source "https://example.com/nuget/" --name test \
    --username u --password p --store-password-in-clear-text

Fails immediately:
error: Failed to read NuGet.Config due to unauthorized access. Path: '/root/.nuget/NuGet/NuGet.Config'.
error:   Access to the path '/root/.nuget/NuGet/NuGet.Config' is denied.
error:   Operation not permitted

### Which .NET image(s) are you using?

mcr.microsoft.com/dotnet/sdk@sha256:620e765fe18186c08399f7aa978f79f04b6bbf0ee1b3b8a91e2d5c9619e59da1

### Steps to reproduce

### Steps to reproduce

**1. Minimal Dockerfile:**
```dockerfile
FROM mcr.microsoft.com/dotnet/sdk@sha256:620e765fe18186c08399f7aa978f79f04b6bbf0ee1b3b8a91e2d5c9619e59da1
RUN dotnet nuget add source "https://api.nuget.org/v3/index.json" --name test \
    --username u --password p --store-password-in-clear-text

build it:
docker build -t repro .

Result:
error: Failed to read NuGet.Config due to unauthorized access. Path: '/root/.nuget/NuGet/NuGet.Config'.
error:   Access to the path '/root/.nuget/NuGet/NuGet.Config' is denied.
error:   Operation not permitted


Confirm the fix — swap the digest to
sha256:d8ee39817ca03a3757288e83c37ed73cc969a286c603b827c7cbe33add1c2d1c in any of the above
and it works cleanly with zero other changes.

Expected behavior
dotnet nuget add source / dotnet restore work as they did on the previous image digest.



### Other information

_No response_

### Output of `docker version`

```console
Version info
Image: mcr.microsoft.com/dotnet/sdk:10.0-alpine
SDK reported inside container: 10.0.400
Alpine base (musl libc)

Output of docker info

Activity

  1. lbussell commented on Aug 24, 2026

    @lbussell
    Member

    [Triage] Hi @whighsmith,

    The image was updated from Alpine 3.23 to 3.24 with the 10.0.400 release. It is possible something changed because of that. If you try with the 10.0-alpine3.23 tag, then we will know if your issue is caused by a change in the Alpine base image.

    I tried to reproduce your issue and I was unable to on Windows 11 amd64 and arm64 using Docker Desktop with the WSL backend. Can you please provide some more information about what host you're running on? What distro and what kernel version? What docker version?

  2. whighsmith commented on Aug 28, 2026

    @whighsmith
    Author

    Thanks for looking into this. Here's the host info you asked for:

    NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" VERSION_ID="7"

    • Kernel: 3.10.0-1160.119.1.el7.x86_64
    • Docker: 26.1.4, build 5650f9b

    I also tried to reproduce this on a modern host (Windows 11 + Docker Desktop/WSL2, similar to what you tested) and could not reproduce it there either; it only reproduces on this CentOS 7 build agent. And per your suggestion: pinning to 10.0-alpine3.23 on that same CentOS 7 host fixes it completely, with zero other changes. So this does look like it's specific to the Alpine 3.23 → 3.24 bump interacting with this particular (very old) kernel, not the SDK/NuGet client itself, and not something that reproduces on newer kernels.

    My guess at the root cause:

    The stock CentOS 7 kernel (3.10.x, RHEL 7 lineage, EOL since mid-2024) is old enough that it predates or has incomplete support for whatever syscall Alpine 3.24's updated musl libc started using for its atomic temp-file-write pattern (write to a temp file, then rename into place); something in the renameat2/statx family seems most likely, since NuGet/.NET use exactly that pattern everywhere a failure was observed (NuGet.Config, the HTTP cache, NuGetScratchroot, and obj/*.tmp), regardless of which directory it happened in. Docker's default seccomp profile only allowlists known syscalls; when a container issues a syscall the profile/kernel doesn't recognize or support, it typically comes back as EPERM ("Operation not permitted") rather than a clearer "not supported" error, which matches the exact symptom we saw and explains why it's path-independent and why it doesn't reproduce on any modern-kernel host (WSL2, or presumably any current mainstream distro).

    If that's on the right track, it might be worth a note in the release/image docs that Alpine 3.24-based images now have a minimum practical host kernel requirement higher than before, since this wouldn't be something dotnet-docker itself can "fix". It's a genuine platform floor being raised.

  3. self-assigned this
    on Sep 21, 2026
  4. added theissue type on Sep 28, 2026
  5. moved this from Backlog to Sprint in .NET Dockeron Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions