| Tested on | Red Hat Enterprise Linux 10.2 (Podman 5.8.2 pre-upgrade inventory); Fedora Rawhide container (Podman 6.1.0 post-upgrade validation via dnf install podman) |
|---|---|
| Package | podman-5.8.2-5.el10_2.x86_64 (RHEL 10 lab)podman-6.1.0-1.fc46 (Fedora Rawhide validation) |
| Applies to | Linux hosts upgrading from Podman 5.x to Podman 6.x through a distribution package (RHEL, Rocky, AlmaLinux, Fedora, CentOS Stream) |
| Privilege | sudo for package upgrade and rootful checks; normal user for rootless validation |
| Scope | Breaking changes, pre-upgrade inventory, BoltDB→SQLite migration on 5.8.x, CNI and slirp4netns removal, cgroup v2 and firewall checks, Netavark isolation testing, configuration and Quadlet review, distribution upgrade path, post-upgrade validation, and migration troubleshooting. Does not cover Podman Desktop, macOS/Windows, generic install, or full networking/Quadlet tutorials. |
| Related guides | Install Podman on RHEL |
Podman 6 is a migration release, not a drop-in minor bump. BoltDB, CNI, slirp4netns, cgroups v1, and the iptables firewall backend are gone. The biggest upgrade risks are database state, legacy CNI networking, slirp4netns configuration, cgroups v1, and Podman 5 configuration carried forward without verification.
This guide answers one question: what can break when you move an existing Linux Podman 5 installation to Podman 6, and how to perform and verify that migration safely.
Podman 5 to 6 migration: breaking changes at a glance
| Podman 5-era behavior / component | Podman 6 |
|---|---|
| BoltDB supported | BoltDB removed; SQLite required |
| CNI supported | CNI removed |
| slirp4netns supported | Removed; pasta is the rootless path |
| cgroups v1 supported | Removed; cgroups v2 required |
| iptables firewall backend | Removed; use nftables or applicable firewalld integration |
| Older Netavark isolation defaults | Stricter cross-network isolation |
| Legacy configuration lookup | Rewritten containers.conf / drop-in parsing |
| Older Quadlet install layout | Subdirectory layout; verify after upgrade |
podman volume prune removes all unused volumes |
Removes unused anonymous volumes; use --all for previous behavior |
Treat the table as a checklist, not marketing copy. Each row is something you verify on Podman 5.8 before you install the Podman 6 package from your distribution.
Should you upgrade to Podman 6 manually?
Start with what your Linux distribution officially ships. Enterprise Linux and Ubuntu LTS releases may stay on Podman 5.8.x for months while maintainers rebases dependencies (Netavark 2.x, Buildah, Skopeo). Podman 5.8 remains an active maintenance branch during the transition.
| Situation | Recommendation |
|---|---|
| RHEL / Rocky / Alma / Ubuntu LTS on supported Podman 5.8 | Upgrade through the distribution package when Podman 6 appears in your repos — not from upstream binaries |
| Fedora Rawhide or another rolling release already on 6.x | Follow this guide's validation steps after dnf upgrade |
| Production host where 5.8 meets your needs | Stay on 5.8 until you have a tested migration window; newer upstream is not automatically better |
On the RHEL 10 lab host in August 2026, AppStream still provided podman-5.8.2. Fedora Rawhide shipped podman-6.1.0 — useful for post-upgrade validation, not a license to replace RHEL's supported package with Rawhide RPMs.
Check your Podman 5 environment before upgrading
Capture inventory while you are still on Podman 5. You need a baseline if post-upgrade behavior changes.
Confirm the client and API versions:
podman versionSample output from the RHEL 10 lab host:
Client: Podman Engine
Version: 5.8.2
API Version: 5.8.2Record the runtime stack — database backend, network backend, cgroup mode, and rootless network command:
podman infoRead these fields from the lab host (trimmed):
databaseBackend: sqlite
cgroupVersion: v2
networkBackend: netavark
rootlessNetworkCmd: pasta
Version: 5.8.2List workloads and storage objects you expect to survive the upgrade:
podman ps -apodman ps -a exits quietly when no containers remain; on a busy host you would see every created container ID and name.
Check pod infrastructure separately:
podman pod psList custom networks — especially any created years ago under CNI:
podman network lsSample output:
NETWORK ID NAME DRIVER
2f259bab93aa podman bridgeList named volumes that hold application data:
podman volume lsBack up important volume data and configuration files (containers.conf, storage.conf, registries.conf, Quadlet units). Image layers alone do not protect database content inside volumes.
Also note:
- Custom networks and whether they use Netavark options such as
isolate=true - Active Quadlet units (
podman quadlet list) podman system serviceor API/socket consumers- Legacy paths such as
/etc/cni/net.d/(missing on the lab host — expected on older CNI-era installs) - Rootless users and their
~/.config/containers/overrides
Migrate BoltDB to SQLite before Podman 6
Podman 6 removes BoltDB entirely. Hosts still on BoltDB must convert to SQLite on Podman 5.8.x before the major upgrade — or immediately when Podman 6 refuses to start with a migration error.
Do not pin podman-5.8.0 and stop. The BoltDB→SQLite migration path landed in 5.8.0, but later 5.8.x releases fixed migration edge cases. Move to the newest Podman 5.8.x your distribution ships, then migrate.
Check the active database backend:
podman info --format 'database={{.Host.DatabaseBackend}}'Sample output on the lab host (already migrated):
database=sqliteWhen the backend is still boltDB, plan migration before you rely on Podman 6 workloads. Podman 5.8 had a documented high-impact migration concurrency bug — concurrent Podman processes can race the conversion. If you choose manual migration, stop containers and other Podman consumers and perform it in a maintenance window with no concurrent Podman commands. Upstream generally prefers reboot-time migration because it minimizes this race.
Run the supported conversion on Podman 5.8.x:
podman system migrate --migrate-dbOn the lab host where SQLite was already active, Podman stopped running containers and reported:
No migration is necessary: backing database is already SQLiteThe command exits with no output when migration succeeds on a host that needed conversion. The legacy BoltDB file is left on disk until you remove it manually — see podman system migrate for full command behavior, not repeated here.
Verify before installing Podman 6:
podman info --format 'database={{.Host.DatabaseBackend}}'You want database=sqlite and a clean podman ps -a listing your expected containers.
Replace CNI networking with Netavark
Podman 6 drops CNI completely. If podman info still shows networkBackend: cni or /etc/cni/net.d/ contains custom conflists, migrate networking on Podman 5.8 first.
Confirm the backend:
podman info --format 'network={{.Host.NetworkBackend}}'Sample output on the lab host:
network=netavarkInspect existing networks:
podman network lsRecreate or adjust any network still tied to CNI plugins before the major upgrade. Custom bridge definitions, macvlan parents, and DNS settings belong in Netavark network JSON — see Podman networking for design and troubleshooting, not in this migration checklist.
Replace slirp4netns with pasta
Podman 6 removes slirp4netns. Rootless hosts must use pasta (the passt package on RHEL and Fedora).
Check the rootless network command for your test user:
podman info --format 'rootlessNetworkCmd={{.Host.RootlessNetworkCmd}}'Sample output for user podtest on the lab host:
rootlessNetworkCmd=pastaSearch configuration for legacy slirp references before upgrading:
grep -R slirp /etc/containers/ ~/.config/containers/ 2>/dev/nullNo output means you are not overriding the default with slirp4netns options. If grep finds slirp4netns entries in containers.conf, rewrite them for pasta before Podman 6 — see Rootless Podman networking for pasta options and port-forward retests.
Verify cgroups v2 before upgrading
Podman 6 requires cgroup v2. Hosts still on cgroup v1 cannot run Podman 6 until the OS uses unified cgroups.
Check the cgroup filesystem type:
stat -fc %T /sys/fs/cgroup/Sample output on the lab host:
cgroup2fscgroup2fs confirms cgroup v2. If you see tmpfs with v1 controllers mounted separately, stop and migrate the host OS first — Podman 6 will not fix that.
Cross-check from Podman:
podman info --format 'cgroup={{.Host.CgroupVersion}}'Sample output:
cgroup=v2Verify network firewall compatibility
Podman 6 / Netavark 2 removes the legacy iptables firewall backend. Hosts must use a supported current backend, such as nftables or the applicable firewalld integration.
Before upgrading, note:
- Host firewall (
firewalld,nftablesrulesets, or cloud security groups) - Published ports on production containers
- Custom bridge networks and DNS forwarders
After upgrading, explicitly retest:
- Host → container published ports
- Container → Internet egress
- Container DNS resolution
- Container-to-container traffic on the same network
Firewall debugging belongs in your platform docs; this migration guide only flags the retest requirement.
Check Podman 6 network isolation changes
Netavark 2.x enforces stricter isolation between Podman networks. Workloads on different networks that could reach each other by IP on Podman 5 may fail after Podman 6.
On Podman 5.8, create two default bridge networks and two containers:
podman network create net-aCreate the second network on a separate bridge:
podman network create net-bStart the first container on net-a:
podman run -d --name demo-a --network net-a docker.io/library/alpine:3.20 sleep 600Attach the second container to net-b:
podman run -d --name demo-b --network net-b docker.io/library/alpine:3.20 sleep 600Read the IP address on net-b:
podman inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' demo-bSample output:
10.89.1.3From demo-a, ping that IP across networks:
podman exec demo-a ping -c1 -W2 10.89.1.3On Podman 5.8 with default network options, cross-network ping succeeded in the lab:
64 bytes from 10.89.1.3: seq=0 ttl=42 time=0.876 msPodman 6 tightens this behavior. Plan connectivity tests after upgrade; if cross-network traffic is required, redesign networks or evaluate supported isolate=false options during network creation — then retest with real application traffic, not only ping.
To model isolated networks on Podman 5.8 before upgrade:
podman network create net-iso-a -o isolate=trueCreate the second isolated network the same way:
podman network create net-iso-b -o isolate=trueCross-network ping between containers on isolated networks failed in the lab (100% packet loss), matching the direction Podman 6 defaults enforce more broadly.
Clean up lab containers when finished:
podman rm -f demo-a demo-b 2>/dev/nullReview containers.conf, storage.conf, and registries.conf
Podman 6 rewrote configuration file parsing and drop-in lookup. Custom settings from Podman 4 or early Podman 5 may be ignored or interpreted differently.
Check distribution defaults and drop-ins:
ls /etc/containers/*.conf /etc/containers/containers.conf.d/ 2>/dev/nullSample output on the lab host:
/etc/containers/registries.confFor each override in /etc/containers/ and ~/.config/containers/, ask:
- Is the key still supported in Podman 6?
- Did the default change?
- Does the file path still match the new lookup order under
/usr/share/containers/?
Do not paste entire configuration references here. Compare your files against current containers.conf(5), storage.conf(5), and registries.conf(5) after upgrading.
Review automation that calls podman volume prune. Podman 6 matches Docker and prunes only unused anonymous volumes. To keep the Podman 5-era behavior of pruning all unused volumes, scripts must pass --all:
podman volume prune --allCheck Quadlet before and after the upgrade
Quadlet unit layout changed in the Podman 6 generation — installed applications move from flat .app bundles to subdirectory layouts. Migration-related checks only:
List installed Quadlets:
podman quadlet listSample output on the lab host (no user-installed units):
NAME UNIT NAME PATH ON DISK STATUS APPLICATIONAfter upgrading, reload systemd and verify generators still emit services:
systemctl daemon-reloadInspect a known unit's source path:
systemctl show -p SourcePath myapp.serviceReplace myapp.service with your generated unit name. For install paths, .container syntax, and generator failures, use Podman Quadlet with systemd and Podman Quadlet troubleshooting — not duplicated in this migration guide.
Check podman image trust changes
Podman 6 requires an explicit signature policy file when you set registry trust with the CLI.
On Podman 5.8, podman image trust set --help lists --pubkeysfile and --type but no --signature-policy flag.
On Podman 6.1.0 (Fedora Rawhide validation), the same help adds:
--signature-policy string Path to a signature-policy filePlan for mandatory --signature-policy in automation that calls podman image trust set. Full signing workflows belong in the Podman image signing guide.
Upgrade Podman to version 6
Perform the package upgrade only after the checks above pass. Use your distribution's supported repository — not ad hoc upstream RPMs over RHEL or Ubuntu packages.
When Fedora Rawhide (or your rolling release) ships Podman 6:
sudo dnf upgrade podmanOn RHEL, Rocky, or AlmaLinux, wait until AppStream publishes podman 6.x, then use the same dnf upgrade podman path documented in Install Podman on Rocky Linux.
Confirm the new major after upgrade:
podman versionSample output from Fedora Rawhide validation (Podman 6.1.0):
podman version 6.1.0Re-run podman info and confirm SQLite, netavark, pasta, and cgroup v2:
podman info 2>&1 | grep -E 'databaseBackend|cgroupVersion|networkBackend|rootlessNetworkCmd|^ Version:'Sample output from Fedora Rawhide validation:
databaseBackend: sqlite
cgroupVersion: v2
networkBackend: netavark
rootlessNetworkCmd: pasta
Version: 6.1.0Post-upgrade validation
Walk this sequence on the upgraded host — do not treat it as a checkbox you skip.
Confirm Podman starts without database errors:
podman info --format 'database={{.Host.DatabaseBackend}} version={{.Version.Version}}'Sample output:
database=sqlite version=6.1.0Verify existing objects are visible:
podman ps -aList images with repository tags so you can spot missing layers:
podman images --format '{{.Repository}}:{{.Tag}}'Confirm pod infrastructure survived the upgrade:
podman pod psCheck custom networks still exist:
podman network lsNamed volumes should still appear in local storage:
podman volume lsRun a rootless smoke test as a non-root user:
podman info --format 'rootless={{.Host.Security.Rootless}}'Sample output for podtest:
rootless=truePull and run a hello container to exercise registry, runtime, and storage:
podman run --rm quay.io/podman/helloSample output:
!... Hello Podman World ...!Retest published ports, DNS, cross-container connectivity on shared networks, volume mounts, SELinux volume labels, Quadlet services, and any podman compose workflows you rely on. Reboot the host once to confirm systemd-managed containers survive logout and restart.
Common errors after upgrading to Podman 6
| Symptom | Likely cause | Fix |
|---|---|---|
| Podman refuses to start; message mentions BoltDB or database migration | SQLite migration incomplete | On Podman 5.8.x stop all containers and Quadlets; run podman system migrate --migrate-db; verify databaseBackend: sqlite before retrying 6.x |
networkBackend: cni or CNI plugin errors |
Legacy CNI config still present | Move networks to Netavark on 5.8; remove /etc/cni/net.d dependencies; recreate networks |
| Rootless failures referencing slirp4netns | slirp4netns removed in 6 | Switch to pasta in containers.conf; retest port forwards per rootless networking guide |
| Immediate exit citing cgroups v1 | Host still on cgroup v1 | Migrate host to cgroup v2 before Podman 6 |
| Containers on different networks no longer reach each other | Stricter Netavark isolation | Redesign networks; retest with isolate=false only when appropriate; verify with application probes |
| Quadlet unit missing or wrong path after upgrade | Podman 6 layout change | Run podman quadlet list; daemon-reload; compare generator output with Quadlet troubleshooting guide |
podman volume prune no longer removes unused named volumes |
Podman 6 now prunes only unused anonymous volumes by default | Use podman volume prune --all when you intentionally want all unused volumes removed |
podman image trust set fails without policy path |
--signature-policy now required |
Pass a signature-policy file explicitly |
Can you downgrade from Podman 6 to Podman 5?
Do not depend on downgrade as your rollback plan. Podman 5.8 understands SQLite, which helps database compatibility, but networking defaults, configuration parsing, and Quadlet layouts may not match.
Whether dnf downgrade podman or apt install podman=<old-version> works depends on your distribution's repository history — there is no universal recipe. Filesystem snapshots, volume backups, and exported images remain the reliable rollback strategy.
If you must attempt downgrade, stop all containers first and expect to reconcile Netavark networks and Quadlet paths manually.
References
Summary
Podman 6 removes legacy plumbing that Podman 5 already deprecated: BoltDB, CNI, slirp4netns, cgroups v1, and the iptables network backend. The safe path is inventory on Podman 5.8.x, migrate any remaining BoltDB state to SQLite using the supported reboot-time migration path or a controlled podman system migrate --migrate-db maintenance window, confirm netavark and pasta, verify cgroup v2, then upgrade through your distribution's package manager when Podman 6 is officially available.
On the RHEL 10 lab host, Podman 5.8.2 already used SQLite, netavark, pasta, and cgroup v2 — the migration command reported no work left. Network isolation testing showed cross-network IP reachability on default Podman 5 bridges but blocked traffic when isolate=true, matching the stricter defaults readers see after Netavark 2.x on Podman 6. Fedora Rawhide validation with podman 6.1.0 confirmed the post-upgrade stack and the new mandatory --signature-policy flag on podman image trust set.
Do not chase upstream Podman 6 on a distribution still shipping 5.8 unless you own the maintenance cost. When AppStream or Ubuntu archives publish 6.x, rerun the post-upgrade validation sequence before you declare production ready.

