docker/compose · error
can't access os.tempDir %s: %w
Error message
can't access os.tempDir %s: %w
What it means
Before invoking buildx bake, compose generates a unique metadata-file name under os.TempDir() by stat-ing candidate names until one is free. If stat fails with an error other than NotExist — and is a *fs.PathError — the temp directory itself is considered unusable and this error wraps the underlying path error. It means the OS refused to stat inside the temp dir (permission denied, I/O error, or the path vanished).
Source
Thrown at pkg/compose/build_bake.go:291
if options.Print {
_, err = fmt.Fprintln(s.stdout(), string(b))
return nil, err
}
logrus.Debugf("bake build config:\n%s", string(b))
tmpdir := os.TempDir()
var metadataFile string
for {
// we don't use os.CreateTemp here as we need a temporary file name, but don't want it actually created
// as bake relies on atomicwriter and this creates conflict during rename
metadataFile = filepath.Join(tmpdir, fmt.Sprintf("compose-build-metadataFile-%s.json", uuid.New().String()))
if _, err = os.Stat(metadataFile); err != nil {
if os.IsNotExist(err) {
break
}
var pathError *fs.PathError
if errors.As(err, &pathError) {
return nil, fmt.Errorf("can't access os.tempDir %s: %w", tmpdir, pathError.Err)
}
}
}
defer func() {
_ = os.Remove(metadataFile)
}()
buildx, err := s.getBuildxPlugin()
if err != nil {
return nil, err
}
args := []string{"bake", "--file", "-", "--progress", "rawjson", "--metadata-file", metadataFile}
// FIXME we should prompt user about this, but this is a breaking change in UX
for _, path := range read {
args = append(args, "--allow", "fs.read="+path)
}
if privileged {View on GitHub (pinned to ddc4b044b6)
Solutions
- Verify TMPDIR exists and is readable/writable: ls -ld "$TMPDIR" /tmp
- Unset a broken TMPDIR or point it at a healthy directory: export TMPDIR=$(mktemp -d)
- Clear stale files if /tmp is full or its metadata is corrupted
- For containerized daemons, ensure the daemon container also has a valid temp dir
Example fix
# before $ export TMPDIR=/opt/tmp # missing or 000 perms $ docker compose build # after $ sudo install -d -m 1777 /opt/tmp $ docker compose build
Defensive patterns
Strategy: validation
Validate before calling
// Before a bake build in constrained environments:
tmp := os.TempDir()
info, err := os.Stat(tmp)
if err != nil || !info.IsDir() || info.Mode().Perm()&0o200 == 0 {
return fmt.Errorf("temp dir %s missing or not writable", tmp)
} Prevention
- Set TMPDIR explicitly to a known-good scratch dir in CI and containers
- Avoid pointing TMPDIR at paths that can vanish mid-run (deleted job workspaces)
- Give builders enough tmpfs space for build metadata and contexts
When it happens
Trigger: TMPDIR pointing to a directory the user cannot stat/read; TMPDIR removed or replaced while a build runs; a full or errored tmpfs; TMPDIR set to a path that is actually a file's broken symlink.
Common situations: Containers or CI runners with a custom TMPDIR that is missing or mode 000; hardened environments restricting /tmp access (noexec/locked-down tmpfs); TMPDIR exported with a typo; snap/containerized docker where the daemon's TMPDIR differs from the client's.
Related errors
- no available sync implementation
- %s must be an integer (found: %q)
- service %q build.platforms does not support value set by DOC
- operation cancelled by user
- cannot combine %s and --remove-orphans
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/f3e6a2dedffe5596.
Report an issue: GitHub.