You run podman run hello-world after a fresh Fedora install
The terminal immediately returns Error: cannot connect to Podman: permission denied while attempting to connect to: /run/user/1000/podman/podman.sock. You instinctively prefix the command with sudo. It works, but now your container layers are owned by root, your volume mounts are locked, and your development workflow is broken. This is the standard rootless container setup problem on Fedora.
What's actually happening
Podman defaults to rootless containers on modern Fedora releases. Rootless means the container runtime executes under your user ID instead of escalating to root. It communicates through a Unix socket located in your runtime directory. When that socket is missing, unreadable, or blocked by a misconfigured storage backend, the client refuses to proceed. The system is not broken. The group membership or storage driver simply needs to align with your active user session.
Think of the runtime directory like a private office. The podman group is the key ring. If your user account is not on that ring, the door stays locked. If the storage driver is set to vfs instead of fuse-overlayfs, the filesystem layers cannot stack efficiently, and the runtime aborts before the socket even appears. Fedora ships with the correct defaults, but manual tweaks, third-party guides, or leftover Docker configurations often overwrite them.
Rootless containers rely on user namespaces to map your unprivileged user ID to a root ID inside the container. The kernel requires explicit sub-ID allocations for this mapping. Fedora handles this automatically through systemd and shadow-utils, but the allocations must exist in /etc/subuid and /etc/subgid. If those files are missing or truncated, the runtime cannot create the namespace and returns a permission error. The podman group membership tells the PAM stack to trigger the automatic allocation on login. Without it, the namespace setup fails silently until you try to run a container.
The fix
Start by ensuring your user account belongs to the podman group. This grants the necessary permissions to access the runtime socket and manage container processes without root privileges.
# Add your current user to the podman group without removing existing groups
sudo usermod -aG podman $USER
# Apply the group change to the current shell session immediately
newgrp podman
Group membership changes do not apply to already-running processes. The newgrp command starts a new shell with the updated group list. If you are using a desktop environment, log out and log back in to ensure all GUI tools and terminal emulators inherit the correct permissions.
Next, verify the storage driver configuration. Fedora relies on fuse-overlayfs for rootless containers. The vfs driver works but creates a separate copy of every layer, which exhausts disk space quickly and slows down image pulls.
# Check the current storage driver in use
podman info --format '{{.Store.GraphDriverName}}'
If the output shows vfs, you need to override the default. Never edit files in /usr/lib/containers/. Those files ship with the package and get overwritten on updates. Create a user-level override in your home directory instead.
# Create the user configuration directory if it does not exist
mkdir -p ~/.config/containers
# Copy the system default to your home directory for safe editing
cp /usr/share/containers/storage.conf ~/.config/containers/storage.conf
Open ~/.config/containers/storage.conf in your editor. Locate the [storage] section and set the driver explicitly.
[storage]
# Override the system default to use fuse-overlayfs for rootless containers
driver = "fuse-overlayfs"
# Point the graphroot to your home directory so root privileges are not required
graphroot = "/home/$USER/.local/share/containers/storage"
# Point the runroot to your runtime directory for temporary container data
runroot = "/run/user/$(id -u)/containers"
Save the file. Restart the podman systemd socket to apply the new configuration. Fedora uses socket activation for rootless containers, which means the daemon only starts when you run a podman command.
# Reload the systemd user manager to pick up new unit files
systemctl --user daemon-reload
# Restart the podman socket to apply the new storage configuration
systemctl --user restart podman.socket
Run journalctl first. Read the actual error before guessing.
Verify it worked
Confirm the runtime is healthy and the storage driver is active.
# Print the full runtime information to verify socket connectivity and driver
podman info
Look for GraphDriverName: fuse-overlayfs in the output. Run a test container to validate the full lifecycle.
# Pull and run a minimal image, then remove it automatically
podman run --rm docker.io/library/hello-world
The output should show the standard "Hello from Docker!" message without permission errors. Check the container storage path to confirm it lives in your home directory.
# List the storage layers to verify they are owned by your user
podman system df
Reboot before you debug. Half the time the symptom is gone.
Common pitfalls and what the error looks like
The most frequent mistake is editing /usr/lib/containers/storage.conf. Package managers overwrite that file during updates. Your custom driver setting disappears, and the next dnf upgrade silently breaks your rootless setup. Always use ~/.config/containers/storage.conf for user-level overrides. Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/.
Another common trap is mixing sudo podman with rootless workflows. When you run podman with sudo, it creates a separate rootful storage tree in /var/lib/containers. Your rootless containers and your root containers cannot share volumes or networks. You will see Error: no such image or permission denied when trying to access files created by the other mode. Stick to one mode per project.
SELinux denials appear when you bind-mount host directories into containers. The error reads Error: OCI runtime error: permission denied. The container process cannot access the host path because the SELinux context does not allow container processes to read it. Add the :Z or :z suffix to the volume mount to relabel the directory automatically.
# Mount a host directory with automatic SELinux relabeling for container access
podman run -v /home/user/project:/app:Z --rm alpine ls -l /app
If the storage driver falls back to vfs, you will notice rapid disk usage growth. A 200 megabyte base image creates a 200 megabyte copy for every container that uses it. Switch to fuse-overlayfs to share layers efficiently. The FUSE driver handles the overlay filesystem in userspace, which is why root privileges are not required.
If the boot menu is gone, GRUB rescue is your friend, not your enemy.
When to use this vs alternatives
Use rootless Podman when you are running development containers, CI pipelines, or isolated services on a personal workstation. Use rootful Podman when you need to bind to privileged ports below 1024 or manage low-level network namespaces. Use Docker when your organization mandates a single daemon architecture and you are willing to accept root-level container processes. Use Podman Machine when you need to run Linux containers on macOS or Windows hosts. Stay on the upstream rootless configuration if you only deviate from the defaults occasionally.