Podman Netavark and Aardvark DNS
Two Rust binaries in /usr/lib/podman that you never invoke: netavark configures the network and aardvark-dns answers name lookups. They replaced CNI in Podman 4, and neither is on your PATH.
Networking Guide 26 of 47 Intermediate
- OSUbuntu 26.04 LTS (resolute)
- Podman5.7.0
- Runtimecrun 1.21
- Networknetavark 1.16.1
- TimeAbout 13 min
- Reviewed22 August 2026
Written against the versions above. Podman follows the distribution here rather than a vendor repository, so the version you get is the one Ubuntu shipped. The commands are stable across 5.x.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| PODMAN01 | 192.168.0.21 | Ubuntu 26.04 LTS | Primary Container Host | 2 Core | 4 GB | 50 GB |
Before you start
- Podman installed - see guide 1.
-
Ask which backend is in use
podman infonames it: netavark 1.16.1. The other possible answer iscni, which is what Podman 3 and earlier used and what you will still see on older hosts - the two are configured completely differently, so this is the first thing to check before following any networking advice.The binaries live in
/usr/lib/podman/:- netavark - sets up interfaces, addresses, routes and firewall rules
- aardvark-dns - a DNS server for container name resolution
- netavark-dhcp-proxy-client - for macvlan setups that take a lease from your real network
Note the directory. As guide 1 found when
command -v netavarkcame back empty, these are not on your PATH - Podman executes them directly. A helper the engine runs is not a command you run, and there is no useful way to invoke netavark by hand.bash Example session podman info --format 'backend={{.Host.NetworkBackend}} version={{.Host.NetworkBackendInfo.Version}}'backend=netavark version=netavark 1.16.1ls /usr/lib/podman/aardvark-dnsnetavarknetavark-connection-testernetavark-dhcp-proxy-clientExpected result
backend=netavark, and four binaries in/usr/lib/podman/.Success conditionYou know which backend this host uses and where its programs live.
-
The default network, and the field that matters
One network exists out of the box, called
podman:driver=bridge subnet=10.88.0.0/16 dns=falseThree things to read here. It is a bridge. Its subnet is 10.88.0.0/16 - not Docker's 172.17, so any firewall rule or documentation assuming 172.17 does not apply. And
dns=false.That last field is the one to remember, and it is the subject of guide 52: aardvark-dns does not serve the default network. The DNS half of the backend exists, and nothing on this host is using it yet.
There is a second surprise waiting in that subnet, which guide 53 covers: rootless, a container on this network does not get a 10.88 address at all.
bash Example session podman network lsNETWORK ID NAME DRIVER2f259bab93aa podman bridgepodman network inspect podman --format 'driver={{.Driver}} subnet={{range .Subnets}}{{.Subnet}}{{end}} dns={{.DNSEnabled}}'driver=bridge subnet=10.88.0.0/16 dns=falseExpected resultOne bridge network with subnet 10.88.0.0/16 and
dns=false.Success conditionYou can name the default network's subnet and say whether DNS is on.
-
aardvark-dns only runs when something needs it
Create a user-defined network and start two containers on it, and a process appears that was not there before:
8459 /usr/lib/podman/aardvark-dns --config /run/user/1000/containers/networks/aardvark-dns -p 53 runIt is started on demand, once a network with
dns=truehas containers on it, and it reads its zone data from a directory under the runroot - the tmpfs path from guide 14, which is why none of this survives a reboot and none of it needs to.This is the same design as the rest of Podman. There is no DNS service running on an idle host, just as there is no container daemon (guide 2); processes exist while something needs them and not before.
One consequence worth knowing:
aardvark-dnsbinds port 53 inside the rootless network namespace, not on your host, so it does not conflict with a resolver you are already running.bash Example session podman network create appnetappnetpodman run -d --network appnet --name alpha docker.io/library/alpine sleep 30069c52943fec12a11a6d2bf31490c60ba143ee79c7499277a13d33c45c98d80b3podman run -d --network appnet --name beta docker.io/library/alpine sleep 3001dd7107d7c4d08cb59d0fadfc9d7f85d80e373f239d06e26ea3464871df0c482pgrep -a aardvark-dns8459 /usr/lib/podman/aardvark-dns --config /run/user/1000/containers/networks/aardvark-dns -p 53 runExpected resultA created network, two containers, and an aardvark-dns process reading from
/run/user/1000/.Success conditionYou can point at the DNS server process and the directory it reads.
Troubleshooting
podman inforeportscnirather thannetavark.Why: An older Podman, or a host upgraded from one - the backend is not switched automatically because existing networks are in the old format.
Fix:
podman system resetmigrates by starting over, which destroys networks and containers. On a host with anything on it, plan the migration rather than running that.netavark: command not found.Why: It is not on your PATH by design.
Fix:You are not meant to run it.
/usr/lib/podman/netavark --versionworks if you need the version, but Podman reports it inpodman infoalready.Container name resolution fails and aardvark-dns is not running.
Why: The containers are on a network with
dns=false- almost always the defaultpodmannetwork.Fix:Create a user-defined network. See guide 52.