Go version

go version go1.25rc1 windows/amd64

Output of go env in your module/workspace:

set AR=ar
set CC=gcc
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_ENABLED=0
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set CXX=g++
set GCCGO=gccgo
set GO111MODULE=
set GOAMD64=v1
set GOARCH=amd64
set GOAUTH=netrc
set GOBIN=
set GOCACHE=C:\Users\ContainerUser\AppData\Local\go-build
set GOCACHEPROG=
set GODEBUG=
set GOENV=C:\Users\ContainerUser\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFIPS140=off
set GOFLAGS=
set GOGCCFLAGS=-m64 -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Windows\TEMP\go-build662705847=/tmp/go-build -gno-record-gcc-switches
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMOD=NUL
set GOMODCACHE=C:\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTELEMETRY=local
set GOTELEMETRYDIR=C:\Users\ContainerUser\AppData\Roaming\go\telemetry
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.25rc1
set GOWORK=
set PKG_CONFIG=pkg-config

What did you do?

Running a build inside a fresh Windows Nano Server container which defaults to the unprivileged ContainerUser and TMP is set to C:\Windows\TEMP: commands such as go build and go run fail to clean up from C:\Windows\Temp with go: open C:\Windows\TEMP: Access is denied.

package main

import "fmt"

func main() {
    fmt.Printf("Hello World!\n")
}

(saved as hello.go)

What did you see happen?

C:\go>go build -o hello.exe hello.go
go: open C:\Windows\TEMP: Access is denied.

What did you expect to see?

When I do the same exact process with Go 1.24, it works fine without errors.

Comment From: tianon

See also https://github.com/docker-library/golang/issues/563, especially https://github.com/docker-library/golang/issues/563#issuecomment-2968325383 -- I bisected this and got the following:

6d418096b2dfe2a2e47b7aa83b46748fb301e6cb is the first bad commit
commit 6d418096b2dfe2a2e47b7aa83b46748fb301e6cb
Author: Damien Neil <dneil@google.com>
Date:   Fri Mar 28 16:14:43 2025 -0700

    os: avoid symlink races in RemoveAll on Windows

    Make the openat-using version of RemoveAll use the appropriate
    Windows equivalent, via new portable (but internal) functions
    added for os.Root.

    We could reimplement everything in terms of os.Root,
    but this is a bit simpler and keeps the existing code structure.

    Fixes #52745

    Change-Id: I0eba0286398b351f2ee9abaa60e1675173988787
    Reviewed-on: https://go-review.googlesource.com/c/go/+/661575
    Reviewed-by: Alan Donovan <adonovan@google.com>
    Auto-Submit: Damien Neil <dneil@google.com>
    LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

 src/internal/syscall/unix/constants.go      |  2 +-
 src/internal/syscall/unix/nofollow_posix.go |  2 +-
 src/internal/syscall/windows/at_windows.go  |  4 ++--
 src/os/path_windows.go                      | 10 +++++++++
 src/os/removeall_at.go                      | 32 +++++++++--------------------
 src/os/removeall_noat.go                    |  2 +-
 src/os/removeall_unix.go                    | 20 ++++++++++++++++++
 src/os/removeall_windows.go                 | 17 +++++++++++++++
 src/os/root_unix.go                         | 12 +++++++++++
 src/os/root_windows.go                      | 10 ++++++++-
 10 files changed, 83 insertions(+), 28 deletions(-)
 create mode 100644 src/os/removeall_unix.go
 create mode 100644 src/os/removeall_windows.go

https://github.com/golang/go/commit/6d418096b2dfe2a2e47b7aa83b46748fb301e6cb

So it looks like the fix for https://github.com/golang/go/issues/52745 causes a regression in how C:\Windows\Temp is handled? 🙈

Comment From: seankhliao

cc @golang/windows

Comment From: tianon

It's also worth noting that something about running the command changes the state of the system such that running it again works fine and without error (I wasn't able to figure out what that's about).

Edit: ah, if I run with -a to force it to recompile, it also fails again.

Comment From: seankhliao

cc @neild

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: tianon

Windows Nano Server is kind of a PITA, so I spent a little time and was able to reproduce with Server Core too by setting TMP explicitly to C:\Windows\Temp and running as an unprivileged user (which would probably work on a desktop Windows system too, assuming an unprivileged user).