Windows: os.MkdirTemp resolves to inaccessible C:\Windows\SystemTemp when running as SYSTEM on Go 1.21+
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 55/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Stale
- Tech stack
- go
- Domain
- operating-systems
Research direction
Start with snapshot/localmounter_windows.go and trace how the empty directory argument reaches os.MkdirTemp. Then review snapshot/localmounter.go and cmd/buildkitd/main.go around root initialization. Done means Windows builds running as SYSTEM create mount temporary directories under the configured root and mounts no longer fail because of C:\Windows\SystemTemp access errors.
Written by the indexing model from the issue text.
Description
Bug description
os.MkdirTemp("", "buildkit-mount") in snapshot/localmounter_windows.go resolves to C:\Windows\SystemTemp when buildkitd runs as SYSTEM on Go 1.21+. Go 1.21 introduced GetTempPath2 which returns C:\Windows\SystemTemp for SYSTEM accounts instead of C:\Windows\Temp. This path is inaccessible to the buildkitd process, causing all mounts to fail.
Reproduction
Run buildkitd as SYSTEM (e.g. as a Windows service or HostProcess container). Any build fails:
```
failed to mount ...: failed to create temp dir: mkdir C:\Windows\SystemTemp\buildkit-mount1234: Access is denied.
```
Root cause
Go 1.21+ changed os.TempDir() on Windows to call GetTempPath2W instead of GetTempPathW. For the SYSTEM account, GetTempPath2W returns C:\Windows\SystemTemp rather than C:\Windows\Temp. C:\Windows\SystemTemp is ACL'd to deny access to most processes including SYSTEM itself in common configurations.
snapshot/localmounter_windows.go calls os.MkdirTemp("", "buildkit-mount") with an empty dir argument, which resolves via os.TempDir().
Proposed fix
Use {root}/tmp as the temp directory, where root is the buildkitd --root flag value. This keeps temp mounts under the same root directory that buildkitd already manages and has write access to.
```diff
--- a/snapshot/localmounter.go
+++ b/snapshot/localmounter.go
@@ -2,9 +2,23 @@ package snapshot
import (
- "os"
- "path/filepath"
"sync"
"github.com/containerd/containerd/v2/core/mount"
)
+var mountTempDir string
+
+func SetMountTempDir(root string) error {
- dir := filepath.Join(root, "tmp")
- if err := os.MkdirAll(dir, 0o700); err != nil {
-
return err - }
- mountTempDir = dir
- return nil
+}
--- a/snapshot/localmounter_windows.go
+++ b/snapshot/localmounter_windows.go
@@ -39 +39 @@
- dir, err := os.MkdirTemp("", "buildkit-mount")
- dir, err := os.MkdirTemp(mountTempDir, "buildkit-mount")
--- a/cmd/buildkitd/main.go (after os.MkdirAll(root, 0700))
+++ b/cmd/buildkitd/main.go
- if err := snapshot.SetMountTempDir(root); err != nil {
-
return errors.Wrapf(err, "failed to set mount temp dir under %s", root) - }
```
Workaround
Run buildkitd as a native Windows service (via --register-service) rather than directly. Windows services running as SYSTEM use GetTempPathW (not GetTempPath2W), so they get C:\Windows\Temp which is accessible.
Version information
```
buildkitd v0.28.0
Go 1.21+
Windows Server 2022 build 20348.4773
Kubernetes v1.34.2+k0s
```
- Dominant language
- Go
- Stars
- 10.3k
- Forks
- 1.5k
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 48
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from moby/buildkit
-
status/triage
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
area/dockerfile
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
Similar issues
-
optimization optimization:agents-md-curator
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
githubnext/gh-aw-cao#13143 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
blinklabs-io/bursa#904 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
yanet-platform/ipfw-go#129 ·
-
bug confmap/provider/googlesecretmanagerprovider needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
open-telemetry/opentelemetry-collector-contrib#51273 · 2 comments ·
-
bug: AI Gateway client filter lists "Unknown" twice when NULL and literal Unknown clients coexist Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 90/100