vxcontrol/pentagi · warning
failed to set temporary upload file permissions: %w
Error message
failed to set temporary upload file permissions: %w
What it means
After a successful copy, SaveUploadedFileToTemp normalizes the temp file mode to 0644 via dst.Chmod. If the Chmod call fails, the temp file is removed and this error is returned. On standard Linux filesystems Chmod on a file you own essentially never fails; it mostly appears on exotic filesystems or unusual mount options.
Source
Thrown at backend/pkg/flowfiles/files.go:337
if err != nil {
return "", fmt.Errorf("failed to open uploaded file: %w", err)
}
defer src.Close()
dst, err := os.CreateTemp(dir, ".upload-*")
if err != nil {
return "", fmt.Errorf("failed to create temporary upload file: %w", err)
}
tmpPath := dst.Name()
defer dst.Close()
if _, err := io.Copy(dst, src); err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("failed to write temporary upload file: %w", err)
}
if err := dst.Chmod(0644); err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("failed to set temporary upload file permissions: %w", err)
}
return tmpPath, nil
}
func IsWithinDir(absPath, dir string) bool {
return strings.HasPrefix(
filepath.Clean(absPath)+string(filepath.Separator),
filepath.Clean(dir)+string(filepath.Separator),
)
}
func ResolvePulledStagedTarget(stagingDir, cacheRelPath string) string {
candidates := []string{
filepath.Join(stagingDir, filepath.FromSlash(cacheRelPath)),
filepath.Join(stagingDir, path.Base(cacheRelPath)),
}
View on GitHub (pinned to ea665308ba)
Solutions
- Move the upload temp dir to a local POSIX filesystem (e.g. /tmp or a local volume) instead of a network/object-store mount.
- If the storage backend ignores permissions by design, check whether the wrapped error is benign (ENOTSUP/EINVAL on chmod) and tolerate it.
- Verify the process owns the created temp file and no security module blocks chmod.
Defensive patterns
Strategy: fallback
Validate before calling
var probeFile, err = func() (*os.File, error) {
f, err := os.CreateTemp(dir, ".permprobe-*")
if err != nil { return nil, err }
defer f.Close()
if err := f.Chmod(0o644); err != nil {
return nil, fmt.Errorf("chmod unsupported on %s: %w", dir, err)
}
os.Remove(f.Name())
return f, nil
} Try / catch
tmpPath, err := flowfiles.SaveUploadedFileToTemp(fh, dir)
if err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && (errors.Is(pe.Err, syscall.ENOTSUP) || errors.Is(pe.Err, syscall.EINVAL)) {
log.Warn().Err(err).Msg("chmod unsupported on this filesystem; using umask default")
// fall back to a manual copy without Chmod if the strict mode is not required
return
}
return err
} Prevention
- Use local POSIX filesystems (ext4/xfs/tmpfs) for temp upload dirs, not S3-FUSE/CIFS/NFS mounts with restricted chmod.
- Set a restrictive umask (e.g. 022) so temp files are already 0644 without needing Chmod.
- Smoke-test the storage backend's permission semantics in CI before deploying.
When it happens
Trigger: dst.Chmod(0644) returns an error: dir is on a filesystem that does not support chmod (some NFS configs, certain FUSE/S3 mounts, Windows shares), or the file was externally removed/closed abnormally.
Common situations: Backing the upload dir with an S3/FUSE mount or CIFS share that rejects permission changes; a custom os.Chmod-disallowing LSM policy; unusual container security profiles (read-only mounts are caught earlier at CreateTemp).
Related errors
- failed to create temp file: %w
- failed to set temp file permissions: %w
- failed to create tmp directory: %w
- failed to create temporary upload file: %w
- failed to create file '%s': %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/f32032d3dac3e3da.
Report an issue: GitHub.