Podman 5 to Podman 6 Migration: Breaking Changes and Upgrade Guide

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:

bash
podman version

Sample output from the RHEL 10 lab host:

output
Client:        Podman Engine
Version:       5.8.2
API Version:   5.8.2

Record the runtime stack — database backend, network backend, cgroup mode, and rootless network command:

bash
podman info

Read these fields from the lab host (trimmed):

output
databaseBackend: sqlite
  cgroupVersion: v2
  networkBackend: netavark
  rootlessNetworkCmd: pasta
  Version: 5.8.2

List workloads and storage objects you expect to survive the upgrade:

bash
podman ps -a

podman 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:

bash
podman pod ps

List custom networks — especially any created years ago under CNI:

bash
podman network ls

Sample output:

output
NETWORK ID    NAME        DRIVER
2f259bab93aa  podman      bridge

List named volumes that hold application data:

bash
podman volume ls

Back 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 service or 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:

bash
podman info --format 'database={{.Host.DatabaseBackend}}'

Sample output on the lab host (already migrated):

output
database=sqlite

When 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:

bash
podman system migrate --migrate-db

On the lab host where SQLite was already active, Podman stopped running containers and reported:

output
No migration is necessary: backing database is already SQLite

The 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:

bash
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:

bash
podman info --format 'network={{.Host.NetworkBackend}}'

Sample output on the lab host:

output
network=netavark

Inspect existing networks:

bash
podman network ls

Recreate 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:

bash
podman info --format 'rootlessNetworkCmd={{.Host.RootlessNetworkCmd}}'

Sample output for user podtest on the lab host:

output
rootlessNetworkCmd=pasta

Search configuration for legacy slirp references before upgrading:

bash
grep -R slirp /etc/containers/ ~/.config/containers/ 2>/dev/null

No 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:

bash
stat -fc %T /sys/fs/cgroup/

Sample output on the lab host:

output
cgroup2fs

cgroup2fs 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:

bash
podman info --format 'cgroup={{.Host.CgroupVersion}}'

Sample output:

output
cgroup=v2

Verify 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, nftables rulesets, 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:

bash
podman network create net-a

Create the second network on a separate bridge:

bash
podman network create net-b

Start the first container on net-a:

bash
podman run -d --name demo-a --network net-a docker.io/library/alpine:3.20 sleep 600

Attach the second container to net-b:

bash
podman run -d --name demo-b --network net-b docker.io/library/alpine:3.20 sleep 600

Read the IP address on net-b:

bash
podman inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' demo-b

Sample output:

output
10.89.1.3

From demo-a, ping that IP across networks:

bash
podman exec demo-a ping -c1 -W2 10.89.1.3

On Podman 5.8 with default network options, cross-network ping succeeded in the lab:

output
64 bytes from 10.89.1.3: seq=0 ttl=42 time=0.876 ms

Podman 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:

bash
podman network create net-iso-a -o isolate=true

Create the second isolated network the same way:

bash
podman network create net-iso-b -o isolate=true

Cross-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:

bash
podman rm -f demo-a demo-b 2>/dev/null

Review 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:

bash
ls /etc/containers/*.conf /etc/containers/containers.conf.d/ 2>/dev/null

Sample output on the lab host:

output
/etc/containers/registries.conf

For 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:

bash
podman volume prune --all

Check 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:

bash
podman quadlet list

Sample output on the lab host (no user-installed units):

output
NAME        UNIT NAME   PATH ON DISK  STATUS      APPLICATION

After upgrading, reload systemd and verify generators still emit services:

bash
systemctl daemon-reload

Inspect a known unit's source path:

bash
systemctl show -p SourcePath myapp.service

Replace 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:

output
--signature-policy string   Path to a signature-policy file

Plan 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:

bash
sudo dnf upgrade podman

On 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:

bash
podman version

Sample output from Fedora Rawhide validation (Podman 6.1.0):

output
podman version 6.1.0

Re-run podman info and confirm SQLite, netavark, pasta, and cgroup v2:

bash
podman info 2>&1 | grep -E 'databaseBackend|cgroupVersion|networkBackend|rootlessNetworkCmd|^  Version:'

Sample output from Fedora Rawhide validation:

output
databaseBackend: sqlite
  cgroupVersion: v2
  networkBackend: netavark
  rootlessNetworkCmd: pasta
  Version: 6.1.0

Post-upgrade validation

Walk this sequence on the upgraded host — do not treat it as a checkbox you skip.

Confirm Podman starts without database errors:

bash
podman info --format 'database={{.Host.DatabaseBackend}} version={{.Version.Version}}'

Sample output:

output
database=sqlite version=6.1.0

Verify existing objects are visible:

bash
podman ps -a

List images with repository tags so you can spot missing layers:

bash
podman images --format '{{.Repository}}:{{.Tag}}'

Confirm pod infrastructure survived the upgrade:

bash
podman pod ps

Check custom networks still exist:

bash
podman network ls

Named volumes should still appear in local storage:

bash
podman volume ls

Run a rootless smoke test as a non-root user:

bash
podman info --format 'rootless={{.Host.Security.Rootless}}'

Sample output for podtest:

output
rootless=true

Pull and run a hello container to exercise registry, runtime, and storage:

bash
podman run --rm quay.io/podman/hello

Sample output:

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.


Frequently Asked Questions

1. Can I upgrade directly from Podman 5 to Podman 6?

Only after your distribution ships Podman 6 in its supported repositories and you complete pre-upgrade checks. Move to the newest Podman 5.8.x your distro provides, migrate any BoltDB state to SQLite, verify Netavark and pasta, then upgrade with the package manager. Do not overlay an upstream binary on a supported distribution package without a maintenance plan.

2. Do I need to migrate BoltDB before installing Podman 6?

Yes when podman info still reports databaseBackend boltDB or Podman 6 refuses to start with a database migration error. If databaseBackend is still BoltDB, migrate before relying on Podman 6 workloads. On current 5.8.x you can run podman system migrate --migrate-db during a controlled maintenance window, or use the supported reboot-time migration path. Upstream notes that reboot-time migration reduces the chance of races with other Podman processes.

3. What happens to CNI networks when I upgrade to Podman 6?

Podman 6 removes CNI support entirely. Hosts still using the CNI network backend must recreate required networks under Netavark before upgrading. Also inspect /etc/cni/net.d/ for legacy definitions that may still be referenced. Inspect podman network ls and podman info networkBackend on Podman 5.8 first.

4. Why did containers on different Podman networks stop talking after Podman 6?

Podman 6 and Netavark 2.x enforce stricter network isolation by default. Cross-network traffic that worked on Podman 5 may be blocked unless you redesign networking or use supported isolation options such as isolate=false where appropriate. Retest container-to-container connectivity after upgrade.

5. Is it safe to downgrade from Podman 6 to Podman 5?

Do not plan on a painless major-version downgrade. Podman 5.8 can read SQLite databases, but networking defaults, configuration parsing, and Quadlet layout may differ. Take filesystem snapshots or export critical workloads before upgrading; treat downgrade as an emergency recovery path only if your distribution still provides the older package.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)