Go

What are the gotchas of go:embed patterns? Why is my .env or _redirects file missing?

Question 434HardGo 1.22 to 1.25

When a pattern names a directory, files whose names start with . or _ are excluded recursively. So //go:embed dist silently drops dist/.well-known/, _app/ (SvelteKit output) and _redirects. Fixes:

//go:embed all:dist        // include dot/underscore files (Go 1.18+)
var dist embed.FS

//go:embed dist/_app dist/.well-known   // or name them explicitly
var more embed.FS

Other rules:

  • No .., no absolute paths, and nothing outside the module. A matched path cannot cross into another module (a directory with its own go.mod) or into vendor/.
  • Symlinks and irregular files are not supported.
  • A pattern that matches nothing, or an empty directory, is a compile error, which is useful. * does not match /, and there is no **.
  • Paths inside the FS always use forward slashes and have no leading ./. With //go:embed static you open "static/index.html", not "index.html", so use fs.Sub.
  • Embed only works on package-level vars, not locals.
  • Changes to embedded files correctly invalidate the build cache, but for local development you may want os.DirFS behind a flag to get hot reload.
  • Embedded files have a zero ModTime, so http.FileServer sends no Last-Modified header. Use ETags or hashed filenames for caching.

More on Modules, Packages & Tooling

All 36 Modules, Packages & Tooling questions