What Is New in Podman 6.0
| Category | Highlights |
|---|---|
| New Features |
|
| Improvements |
|
| Bug Fixes |
|
| Breaking Changes |
|
| Deprecations |
|
What legacy infrastructure must be replaced before upgrading to Podman 6.0?
Podman 6.0 finalizes the removal of four deprecated subsystems that have been on the deprecation path since Podman 4.x and 5.x: cgroups v1, the BoltDB database, CNI networking, and the slirp4netns rootless network stack. If any of these are still in use, the upgrade will break your environment -- not degrade it gracefully.
The migration checklist before upgrading:
- Cgroups v1 -> cgroups v2: Run
podman info | grep cgroupVersion. If it returnsv1, you need a kernel and OS upgrade or the appropriate cgroup unified hierarchy enabled in your bootloader. - BoltDB -> SQLite: Podman 6 will attempt an automatic migration on first start. However, back up your database first. You can check the backend in use via
podman info --format '{{.Store.DatabaseBackend}}'. - CNI -> Netavark: Run
podman info | grep networkBackend. If it showscni, switch to Netavark before upgrading. Existing CNI network configs are not automatically converted. - slirp4netns -> Pasta: Rootless users relying on slirp4netns need Pasta installed. On most distributions this is the
passtpackage.
In practice, most systems running Podman 5.x with default settings are already on the correct stack. The risk is highest for older RHEL/CentOS 7 style systems still on cgroups v1, or environments that explicitly opted into BoltDB or CNI for compatibility reasons.
How does Podman 6.0 change multi-provider machine management?
All podman machine commands can now operate on VMs from any provider, regardless of which provider is currently set as the default. Previously, the active provider acted as a filter, making it difficult to manage mixed environments -- for example, using both applehv and libkrun VMs on the same Mac, or hyperv and wsl VMs on the same Windows host.
The default provider setting now only controls which provider is used when creating a new VM via podman machine init. You can override this per-creation using the new --provider flag:
podman machine init --provider libkrun my-libkrun-vm
podman machine init --provider applehv my-applehv-vm
podman machine list # shows both VMs regardless of default provider
There are two additional usability improvements here. When you start a VM that is not the current default connection, Podman will interactively ask if you want to update the default. You can suppress this with --update-connection=false. Additionally, the new podman machine os update command lets you update the OS of a machine VM directly -- useful for bootc-based machines -- though this is not supported on the wsl provider.
Watch out for Linux users: machine VMs on Linux now mount host volumes via systemd instead of the previous mechanism. This is a hard break -- existing Linux machine VMs will have broken volume mounts and must be recreated. Back up any data in those mounts first.
What Quadlet improvements ship in Podman 6.0?
Podman 6.0 introduces meaningful improvements to the Quadlet subsystem at both the usability and structural levels. The most impactful operational change is the reworked file layout: Quadlets and their associated files are now placed in subdirectories rather than tracked via a .app file. This makes manual management of Quadlets installed via podman quadlet install considerably less fragile.
Feature additions in this release:
- Quadlet
.volumeunits now acceptUID=,GID=, andOptions=keys, giving you direct control over volume ownership without wrapping it in aExecStartPrehack. - Quadlet
.containerunits now support mounting anonymous volumes with aMount=key that has no source, removing a gap with regularpodman runbehavior. - Two new Quadlet search paths have been added for distribution packaging:
/usr/share/containers/systemd/usersand/usr/share/containers/systemd/users/${UID}. This matters for teams building RPMs or DEBs that ship user-scoped Quadlets. podman quadlet listgains--noheading, a--filter status=filter, and a newPodoutput field.
The manpages have also been split into per-Quadlet-type files, which is a significant quality-of-life improvement when you are quickly checking the key reference for a .network vs a .container unit.
How does the network isolation default change affect existing setups in Podman 6.0?
Network isolation now defaults to enabled in Podman 6.0, aligning with Docker's default behavior. In Podman 5.x, network isolation was disabled by default, and a special workaround existed in the Docker-compatible API to accommodate this. Both the workaround and the old default are gone in 6.0.
This matters if you have containers or Compose-based stacks that relied on implicit cross-network reachability. With isolation enabled by default, containers on different networks cannot reach each other unless explicitly connected. The behavior you want to verify:
# Before: containers on different networks could often reach each other
# After: you need explicit network membership
podman network connect my-shared-network my-container
Two related networking changes round out this area. First, containers created with --net=host now use 127.0.0.1 as their host.containers.internal address rather than a public IP of the host -- which is almost always the correct behavior for local service discovery. Second, podman network create now supports blackhole, unreachable, and prohibit route types via the --route option, which enables proper network policy enforcement at the container network level:
podman network create --route 10.20.30.0/24,blackhole isolated-net
The experimental rootless_port_forwarder="pasta" option in containers.conf is also worth noting: it uses Pasta's kernel-level port forwarding to preserve the original source IP in rootless container traffic, which was previously impossible with the default rootlessport forwarder. The default has not changed, but teams running rootless containers where accurate source IP logging matters should evaluate this option.
What API and configuration changes in Podman 6.0 require attention from tooling authors?
Podman 6.0 includes several API changes that affect tooling built on top of the REST API or Go bindings. The most significant is that the Docker Compatible API version has been bumped to v1.44. Teams using Podman as a Docker drop-in via the Compat API should re-test their integrations.
Key API behavior changes:
- The Compat List endpoint for Containers now returns a
Healthfield with healthcheck status. - The Libpod Pull endpoint now returns error HTTP status codes on pull failure instead of always returning HTTP 200 -- automated pipelines that checked only the response body for errors will need updating.
- The Libpod Pull endpoint now supports a
pullProgress=truequery parameter to stream pull progress. - The Compat Create endpoint for Containers now returns HTTP 409 (not 500) for duplicate container name conflicts.
- CDI device handling in
HostConfig.Devicesvia the Compat Create endpoint has been significantly improved for reliability. - All JSON body parameter endpoints no longer error on an empty body, reducing friction with minimal API clients.
For the Go bindings specifically: the artifacts.Remove() function has had its redundant nameOrID parameter removed, and Podman's import path has changed from github.com/containers/podman/v5 to go.podman.io/podman/v6. Any Go code importing Podman internals will require a go get go.podman.io/podman/v6 and an import path update.
On the configuration side, containers.conf parsing has been significantly rewritten to cleanly separate client and server configuration. Existing config files may need to be reviewed or split. Consult the design doc linked in the official release notes before upgrading in environments with customized containers.conf files.
Frequently Asked Questions about Podman 6.0
Does upgrading to Podman 6.0 require me to rebuild existing containers?
Existing containers do not need to be rebuilt, but any machine VMs on Linux that use volume mounts will need to be recreated because the volume mount mechanism changed from the old approach to systemd-based mounts.
Will Podman 6.0 automatically migrate my BoltDB database to SQLite?
Yes, Podman 6.0 will attempt an automatic migration from BoltDB to SQLite on first start if a BoltDB database is detected, but you should back up your database before upgrading just in case the migration encounters an issue with unusual container state.
What does the podman volume prune behavior change mean for automated cleanup scripts?
In Podman 6.0, running podman volume prune without flags now only removes anonymous unused volumes, matching Docker behavior. Scripts that relied on it pruning all unused volumes must be updated to use the new --all flag instead, for example: podman volume prune --all.
Why did the default podman machine provider on macOS change to libkrun?
The default provider on macOS changed from applehv to libkrun to provide better performance and compatibility on Apple Silicon hardware, though both providers remain supported and you can still explicitly select applehv with the new --provider flag at machine creation time.
How do I check if my system is ready to upgrade to Podman 6.0?
Run podman info and check the cgroupVersion field (must be v2), the networkBackend field (must be netavark), and the databaseBackend field (should be sqlite); also verify that pasta is installed for rootless networking, and that your tooling does not import from github.com/containers/podman/v5 as that path has changed to go.podman.io/podman/v6.
Does the network isolation default change break existing Compose or Kubernetes workflows?
It can, if your existing setup relied on implicit cross-network container reachability that was allowed by Podman 5.x's isolation-disabled default. After upgrading, containers on different networks are isolated by default, and you must explicitly connect containers to shared networks or update your Compose files with the correct network definitions.