vxcontrol/pentagi · error
failed to create temp file: %w
Error message
failed to create temp file: %w
What it means
SaveToTemp creates the temporary file with os.CreateTemp(dir, ".resource-upload-*"); this error wraps CreateTemp's failure. Even when the directory exists, file creation can fail due to permissions, exhausted inodes, or filesystem errors.
Source
Thrown at backend/pkg/resources/resources.go:280
// EscapeLike escapes special LIKE pattern characters (%, _) in s so the string
// can be safely embedded in a SQL LIKE clause.
func EscapeLike(s string) string {
s = strings.ReplaceAll(s, `\`, `\\`)
s = strings.ReplaceAll(s, `%`, `\%`)
s = strings.ReplaceAll(s, `_`, `\_`)
return s
}
// SaveToTemp writes r into a new temporary file in dir and returns the path to
// the temp file. The caller is responsible for removing the temp file on error.
func SaveToTemp(r io.Reader, dir string) (tmpPath string, hash string, size int64, err error) {
if err := os.MkdirAll(dir, 0755); err != nil {
return "", "", 0, fmt.Errorf("failed to create temp directory: %w", err)
}
tmp, err := os.CreateTemp(dir, ".resource-upload-*")
if err != nil {
return "", "", 0, fmt.Errorf("failed to create temp file: %w", err)
}
tmpPath = tmp.Name()
defer tmp.Close()
h := md5.New()
mw := io.MultiWriter(tmp, h)
written, copyErr := io.Copy(mw, r)
if copyErr != nil {
os.Remove(tmpPath)
return "", "", 0, fmt.Errorf("failed to write temp file: %w", copyErr)
}
if err := tmp.Chmod(0644); err != nil {
os.Remove(tmpPath)
return "", "", 0, fmt.Errorf("failed to set temp file permissions: %w", err)
}
return tmpPath, hex.EncodeToString(h.Sum(nil)), written, nil
}View on GitHub (pinned to ea665308ba)
Solutions
- Check write permission on dir for the running user and the mount flags (mount | grep <dir>)
- Check open file descriptor limits (ulimit -n) and raise them if uploads fail under load
- Verify the volume is mounted rw and no security module is denying creation (dmesg/audit logs)
- Ensure dir still exists at call time — don't delete it concurrently
Example fix
// before ulimit -n 1024 # too low for concurrent uploads // after ulimit -n 65536 # or set LimitNOFILE=65536 in the systemd unit
Defensive patterns
Strategy: retry
Validate before calling
func canCreateTemp(dir string) error {
f, err := os.CreateTemp(dir, ".probe-*")
if err != nil {
return err
}
name := f.Name()
f.Close()
return os.Remove(name)
} Try / catch
var tmpPath, hash string
var size int64
err := retry.Do(func() error {
tp, h, s, e := resources.SaveToTemp(r, dir)
if e != nil {
var perr *fs.PathError
if errors.As(e, &perr) && errors.Is(perr.Err, syscall.ENOSPC) {
return retry.Unrecoverable(e) // don't retry disk-full
}
return e
}
tmpPath, hash, size = tp, h, s
return nil
}, retry.Attempts(3)) Prevention
- Raise RLIMIT_NOFILE for services handling many concurrent uploads
- Monitor inode usage, not just disk bytes (df -i)
- Avoid read-only root filesystems without a writable temp volume
- Don't run concurrent cleanup jobs against the temp directory during uploads
When it happens
Trigger: dir exists but is not writable by the process user; the filesystem ran out of inodes; security policies (e.g. read-only tmpfs, AppArmor/SELinux) block creation; too many open file descriptors. Raised via UploadResources or direct calls.
Common situations: ulimit -n exhaustion under heavy upload load; Kubernetes securityContext with readOnlyRootFilesystem; SELinux denials on container volumes; tmp-cleaner scripts removing the directory between MkdirAll and CreateTemp.
Related errors
- failed to create temporary upload file: %w
- failed to set temporary upload file permissions: %w
- failed to create temp directory: %w
- failed to create tmp directory: %w
- failed to write temporary upload file: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/f08a7eef3fdfafe2.
Report an issue: GitHub.