argoproj/argo-workflows · error
failed to create temp file: %w
Error message
failed to create temp file: %w
What it means
BufferReaderToTempFile creates a temp file with os.CreateTemp to buffer an artifact stream before saving. This error wraps the os.CreateTemp failure, meaning the process could not create a file in the system temp dir (os.TempDir, typically /tmp).
Source
Thrown at workflow/artifacts/common/streaming.go:33
if err != nil {
return err
}
defer cleanup()
return save(path)
}
// BufferReaderToTempFile buffers reader into a new temp file (named per the os.CreateTemp
// pattern, e.g. "s3-upload-*") so its content can be re-read multiple times, which most
// storage SDKs require for retry/backoff. It returns the temp file's path and a cleanup
// function that removes it; cleanup is safe to call more than once. On error, any partially
// written temp file is removed before returning, so callers only need to defer cleanup
// after a nil error.
func BufferReaderToTempFile(reader io.Reader, pattern string) (path string, cleanup func(), err error) {
noop := func() {}
tmpFile, err := os.CreateTemp("", pattern)
if err != nil {
return "", noop, fmt.Errorf("failed to create temp file: %w", err)
}
name := tmpFile.Name()
cleanup = func() {
_ = os.Remove(name)
}
if _, err := io.Copy(tmpFile, reader); err != nil {
_ = tmpFile.Close()
cleanup()
return "", noop, fmt.Errorf("failed to buffer stream to temp file: %w", err)
}
if err := tmpFile.Close(); err != nil {
cleanup()
return "", noop, fmt.Errorf("failed to close temp file: %w", err)
}
return name, cleanup, nil
}View on GitHub (pinned to 35bff19146)
Solutions
- Free space on the temp filesystem (df -h /tmp) or expand the node/pod disk.
- Mount a writable tmpfs/emptyDir at /tmp or set TMPDIR to a writable volume.
- If read-only rootfs, add an emptyDir volume and mount it at /tmp (or set TMPDIR to a mounted path).
- Check open-file limits (lsof count, ulimit) for fd leaks; restart the leaking process.
- Set the TMPDIR env var to a larger persistent volume if streams are very large.
Example fix
# before: read-only container, no tmp
spec:
containers: [ ... ]
# after
spec:
containers:
- name: main
volumeMounts: [{name: tmp, mountPath: /tmp}]
volumes:
- name: tmp
emptyDir: {} Defensive patterns
Strategy: validation
Validate before calling
// verify the temp dir is writable and has space before streaming
if info, err := os.Stat(os.TempDir()); err != nil || !info.IsDir() {
return fmt.Errorf("temp dir %s unusable", os.TempDir())
}
if err := unix.Access(os.TempDir(), unix.W_OK); err != nil {
return fmt.Errorf("temp dir not writable: %w", err)
} Try / catch
if err := artifactscommon.SaveStreamViaTempFile(reader, "upload-*", save); err != nil {
if strings.Contains(err.Error(), "failed to create temp file") && errors.Is(err, syscall.ENOSPC) {
return fmt.Errorf("disk full on temp volume — expand /tmp or set TMPDIR")
}
return err
} Prevention
- Mount a writable emptyDir/tmpfs at /tmp (or set TMPDIR) in executor pods.
- Monitor temp-volume disk usage and set alerts below capacity.
- Avoid read-only root filesystems without a tmp mount.
- Check open-fd limits; os.CreateTemp also fails on EMFILE.
When it happens
Trigger: os.CreateTemp returns an error: temp filesystem full (ENOSPC), no read-write /tmp in the container, permission denied on the temp dir, or too many open file descriptors (EMFILE/ENFILE).
Common situations: Pods with a tiny read-only emptyDir at /tmp; node disk pressure; containers run with read-only root filesystem and no tmpfs mount; ulimit -n exhaustion from leaked fds in a long-running controller.
Related errors
- failed to buffer stream to temp file: %w
- failed to copy %s to %s: %w
- failed to close temp file: %w
- failed to create folder path: %w
- failed to create ctr directory: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/f06bc1e0dcdf7666.
Report an issue: GitHub.