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

  1. Move the upload temp dir to a local POSIX filesystem (e.g. /tmp or a local volume) instead of a network/object-store mount.
  2. If the storage backend ignores permissions by design, check whether the wrapped error is benign (ENOTSUP/EINVAL on chmod) and tolerate it.
  3. 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

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


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/f32032d3dac3e3da. Report an issue: GitHub.