Go version

go version go1.22.1 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/cookiengineer/.cache/go-build'
GOENV='/home/cookiengineer/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/cookiengineer/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/cookiengineer/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.1'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/cookiengineer/whatever/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2124737729=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I tried to embed a file called aux.json.gz on GNU/Linux:

//go:embed ./subfolder/aux.json.gz
var embedded_bytes []byte

What did you see happen?

Trying to embed files on GNU/Linux systems that have aux, (or con, nul, prn, com*, lpt*) as a basename of the file cannot be embedded via go:embed.

The reason is a call to isBadEmbedName() in the resolveEmbed() method in go/internal/load/pkg.go.

The isBadEmbedName() method leads to module.CheckFilePath(name) which compares the basename of the file to the badWindowsNames slice in module/module.go.

My questions are now the following:

  • Why is this the case on GNU/Linux systems?
  • Why does go:embed need valid filenames for go modules?
  • Why does go:embed need valid filenames for Windows? Is it unpacked temporarily when the binary is executed later, similar to squashfs, behind the scenes? Why is this not behind a host-specific tag?
  • If the decision is to keep the reserved basenames, COM0 and LPT0 are missing from that list. See the linked article from the module.go file.

What did you expect to see?

I expected to be able to embed filenames when they conform to the POSIX filesystem requirements, so I think it should be possible to embed filenames with the basename of con, prn, aux, nul, com*, lpt* etc.

Comment From: seankhliao

we expect modules to be usable cross platform, so file name restrictions apply everywhere

Comment From: gopherbot

Change https://go.dev/cl/583836 mentions this issue: module: add COM0 and LPT0 to badWindowsNames

Comment From: gopherbot

Change https://go.dev/cl/584335 mentions this issue: cmd: vendor golang.org/x/mod@6686f41

Comment From: matloob

Because it's not clear if those filenames were intender to be excluded in the Microsoft documentation, I will revert this change in x/mod and revendor x/mod. If we get more conclusive evidence that the filenames are indeed excluded, we'll redo for 1.24.

Comment From: cookiengineer

@matloob Which Microsoft documentation are you referring to?

The MSDN / Learn platform article about "Naming a file" that I linked in the initial issue description lists the missing filenames. That very same URL was referenced by the go implementation files, in the comments, added by the initial author(s).

Do not use the following reserved names for the name of a file:

CON, PRN, AUX, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, COM¹, COM², COM³, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, LPT¹, LPT², and LPT³. Also avoid these names followed immediately by an extension; for example, NUL.txt and NUL.tar.gz are both equivalent to NUL. For more information, see Namespaces.

Note

Windows recognizes the 8-bit ISO/IEC 8859-1 superscript digits ¹, ², and ³ as digits and treats them as valid parts of COM# and LPT# device names, making them reserved in every directory. For example, echo test > COM¹ fails to create a file.

Comment From: matloob

@cookieengineer I neglected to link to the issue where the new information came up. I'm sorry about that. Take a look at https://github.com/golang/go/issues/67245#issuecomment-2106341555. @qmuntal works at Microsoft and pointed to the commit that added that file to the documentation. It seems like the commit was added by a non-microsoft contributor and it does not have a descriptive commit message which are both pretty concerning. He also suggests in the comment that another commit seems to conflict with that one. We're going to wait until we have more conclusive information from Microsoft that that change to the Windows documentation is correct before shipping the corresponding change in Go.