Podman DNS and Container Name Resolution with Aardvark DNS

Tested on Red Hat Enterprise Linux 10.2 (Coughlan)
Package podman-5.8.2-5.el10_2.x86_64
netavark-1.17.2-1.el10.x86_64
aardvark-dns-1.17.1-1.el10_2.x86_64
Applies to Linux hosts using Podman with the Netavark/Aardvark network backend
Privilege Rootful examples as root; user-defined bridge DNS behaves similarly rootless; the default rootless network uses pasta
Scope Container-name DNS with Aardvark, DNSEnabled inspection, network aliases, /etc/resolv.conf, --dns / --dns-search / --dns-option, internal and --disable-dns networks, and DNS troubleshooting. Does not cover host access, port publishing, network create options beyond DNS, or general routing and firewall failures.
Related guides Podman networking modes
Podman pod networking

Container name resolution and external DNS are two different paths in Podman. On a normal DNS-enabled bridge, Aardvark answers container names and forwards other queries upstream. On an --internal network, it resolves container names but does not forward external queries.

text
Container
    │ DNS query
Aardvark DNS (bridge gateway)
    ├── container name / alias
    │       → return container IP
    └── external domain (non-internal networks)
            → forward to upstream DNS

The lab image is docker.io/library/alpine:3.20. Most examples use a user-defined network named podman-dns-demo.


How Podman DNS works

Aardvark DNS is Podman's per-network resolver for container names on DNS-enabled bridge networks. For regular containers, Aardvark registers the container name and short container ID, plus network aliases. If you explicitly set --hostname, that hostname is also registered as an alias. Pods have additional DNS behavior covered separately in the Podman pod networking guide. External domains are forwarded to upstream resolvers configured on the host or through podman run --dns flags.

host.containers.internal and host.docker.internal are different — they reach the host through /etc/hosts entries and host-gateway logic, not through Aardvark. See Access the host from a Podman container for host reachability.


Check whether the network has DNS enabled

Do not assume every network runs Aardvark DNS. Inspect the network first:

bash
podman network inspect --format '{{.DNSEnabled}}' podman-dns-demo

On a user-created bridge network the lab returns:

output
true

Compare with the built-in default bridge:

bash
podman network inspect --format '{{.DNSEnabled}}' podman

Sample output on Podman 5.8.2:

output
false

Official Podman 5.8 documentation documents dns_enabled: false on the default podman network while new user-defined bridges enable DNS unless you pass --disable-dns. Treat podman network inspect as authoritative for your installation.

Network Typical DNSEnabled on Podman 5.8.2
Built-in podman false
User-created bridge (no --disable-dns) true

Demonstrate the practical effect on the default bridge. Start a named container there:

bash
podman run -d --name def-web --network podman docker.io/library/alpine:3.20 sleep 600

Try resolving that name from another container on the default bridge:

bash
podman run --rm --network podman docker.io/library/alpine:3.20 sh -c 'getent hosts def-web; echo exit=$?'

Sample output:

output
exit=2

Exit code 2 means getent found no host entry — container names do not resolve on the default bridge here. Create a user-defined network when you need name resolution:

bash
podman network create podman-dns-demo

Resolve containers by name

Start a named container on the DNS-enabled network:

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

From a second container on the same network, resolve the name:

bash
podman run --rm --network podman-dns-demo docker.io/library/alpine:3.20 getent hosts web

Sample output:

output
10.89.0.2         web

The IP is the container address on podman-dns-demo. Bare name web is what applications use.

On DNS-enabled networks, Aardvark registers:

  • Container name (--name web)
  • Short container ID
  • Explicit hostname set with --hostname
  • Network aliases (--network-alias or NETWORK:alias=NAME)

Podman sets the default hostname from the container ID unless you override it with --hostname:

bash
podman inspect web --format 'name={{.Name}} hostname={{.Config.Hostname}}'

Sample output:

output
name=web hostname=aee5387a6e94

The container name web resolves. The default hostname is the short container ID, which is already registered as an alias — so aee5387a6e94 resolves too. An explicit --hostname adds another alias; it does not replace the registered container name.

Add a second service container:

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

Resolve it from another member of the same network:

bash
podman run --rm --network podman-dns-demo docker.io/library/alpine:3.20 getent hosts backend

Sample output:

output
10.89.0.4         backend

Name resolution is more convincing when an application uses it. Run nginx as backend-nginx and fetch by hostname:

bash
podman run -d --name backend-nginx --network podman-dns-demo docker.io/library/nginx:alpine

Fetch the nginx default page using the container hostname:

bash
podman run --rm --network podman-dns-demo docker.io/library/alpine:3.20 wget -qO- http://backend-nginx/ | head -3

Sample output:

output
<!DOCTYPE html>
<html>
<head>

HTTP over the container name confirms DNS and TCP connectivity together.


Use network aliases

Aliases register extra DNS names scoped to one network:

bash
podman run -d --network podman-dns-demo --network-alias database --name postgres-demo docker.io/library/alpine:3.20 sleep 600

Another container resolves the alias:

bash
podman run --rm --network podman-dns-demo docker.io/library/alpine:3.20 getent hosts database

Sample output:

output
10.89.0.8         database

You can also attach with network-scoped alias syntax at create time:

bash
podman run -d --network podman-dns-demo:alias=cache --name cache-demo docker.io/library/alpine:3.20 sleep 600

A container on multiple networks can carry different aliases on each attachment. Adding aliases to a running container belongs in Create and manage Podman networks — this section stays at create-time syntax.


Inspect and override container DNS

On a DNS-enabled user network, the container points at the Aardvark resolver on the bridge gateway:

bash
podman run --rm --network podman-dns-demo docker.io/library/alpine:3.20 cat /etc/resolv.conf

Sample output:

output
search nsn-intra.net lab.example
nameserver 10.89.0.1

10.89.0.1 is the bridge gateway where Aardvark listens. Search domains may include host-inherited entries from the lab VM.

On the default podman network without Aardvark, resolv.conf looks more like a typical host copy — no bridge-gateway nameserver. Do not assume every container inherits host nameservers directly; DNS-enabled bridges always front Aardvark first.

Pass upstream resolvers for external lookups:

bash
podman run --rm --network podman-dns-demo --dns 1.1.1.1 docker.io/library/alpine:3.20 cat /etc/resolv.conf

Sample output:

output
search nsn-intra.net lab.example
nameserver 10.89.0.1

resolv.conf may still list only the Aardvark address. That is expected — Aardvark forwards non-container queries to the servers you passed with --dns. External resolution still works:

bash
podman run --rm --network podman-dns-demo --dns 1.1.1.1 docker.io/library/alpine:3.20 getent hosts example.com

Sample output:

output
104.20.23.154     example.com  example.com

The common confusion — “I set --dns 1.1.1.1 but resolv.conf shows a Podman IP” — is normal on DNS-enabled custom networks. Repeat --dns for additional upstream forwarders; Aardvark still appears as the only nameserver in the file while both addresses are configured for forwarding behind it.

--dns none disables Podman's generation of /etc/resolv.conf. The image's existing /etc/resolv.conf is left unchanged. With an image that does not contain one, the file may be absent:

bash
podman run --rm --network podman-dns-demo --dns none docker.io/library/alpine:3.20 cat /etc/resolv.conf

Sample output with this Alpine image:

output
cat: can't open '/etc/resolv.conf': No such file or directory

Use --dns none only when the image ships its own resolver config or you mount one deliberately.

Add a search suffix with --dns-search example.internal, or pass --dns-search . alone to clear search domains. Resolver options such as --dns-option ndots:1 land in resolv.conf for libc-aware clients.

Netavark 1.15 stopped adding dns.podman to container /etc/resolv.conf. Aardvark can still use that internal domain, but applications should use bare container names or explicit network aliases rather than depending on the dns.podman search suffix.


Internal networks and --disable-dns

Internal bridges block outbound routing but still run Aardvark for container names:

bash
podman network create --internal podman-internal-dns

Start a named container on that isolated bridge:

bash
podman run -d --name int-a --network podman-internal-dns docker.io/library/alpine:3.20 sleep 600

Container names resolve inside the bridge:

bash
podman run --rm --network podman-internal-dns docker.io/library/alpine:3.20 getent hosts int-a

Sample output:

output
10.89.1.2         int-a

External names do not — Aardvark returns NXDOMAIN instead of forwarding:

bash
podman run --rm --network podman-internal-dns docker.io/library/alpine:3.20 sh -c 'getent hosts example.com; echo exit=$?'

Sample output:

output
exit=2

Turn off Aardvark name resolution entirely with --disable-dns:

bash
podman network create --disable-dns podman-no-dns

Verify DNS is off:

bash
podman network inspect --format '{{.DNSEnabled}}' podman-no-dns

Sample output:

output
false

Container names no longer resolve through Podman DNS on that bridge, but external DNS can still work through ordinary resolv.conf nameservers inherited from the host. --disable-dns removes Podman's name plugin, not every resolver inside the container.


Troubleshoot Podman DNS

Work through these layers instead of treating every failure as “DNS is down.”

Confirm both containers share the network you expect:

bash
podman inspect backend --format '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}'

Query whether DNS is enabled on that bridge:

bash
podman network inspect --format '{{.DNSEnabled}}' podman-dns-demo

If this is false, Aardvark will not answer container-name queries on that bridge.

Read the resolver file from a running container:

bash
podman exec web cat /etc/resolv.conf

Look for the bridge-gateway nameserver on DNS-enabled networks versus direct host nameservers on the default bridge.

Test container name resolution from inside web:

bash
podman exec web getent hosts backend

Test external DNS separately on the same container:

bash
podman exec web getent hosts example.com

Ping or curl a known IP to separate name resolution from routing:

bash
podman exec web ping -c 1 -W 2 1.1.1.1

Aardvark DNS is network-scoped. Containers on different bridges do not automatically share name registrations — both must list the same DNS-enabled network for getent hosts backend to work from web.

When the entire container lost outbound connectivity — not just names — a firewall reload may have dropped Netavark rules. Try podman network reload on affected containers as described in Create and manage Podman networks. Do not reset or reinstall Podman for every DNS symptom. Split container-name DNS, external DNS, and routing first.

Symptom Likely cause Fix
Container names fail on default podman bridge DNSEnabled is false Use a user-defined network or enable DNS on a custom bridge
Names fail on custom network --disable-dns or wrong network podman network inspect; recreate network or attach containers correctly
--dns 1.1.1.1 but resolv.conf shows bridge IP Expected Aardvark forwarding Test getent hosts example.com; do not expect 1.1.1.1 in the file
Internal network: names work, external fails --internal bridge design Expected; not a misconfiguration
Names work on one network but not another Containers on different bridges Attach both to the same DNS-enabled network
HTTP to name fails, getent succeeds Service listens on wrong address/port See Fix Podman port mapping not working
Nothing reaches the Internet Routing or firewall See Podman container has no Internet

References


Summary

Podman splits container-name DNS from external resolution. On DNS-enabled bridge networks, Aardvark answers queries for container names, short IDs, explicit hostnames, and network aliases, then forwards external domains upstream. On internal networks it resolves container names only. The built-in podman network on Podman 5.8.2 ships with DNSEnabled false, while user-created bridges default to true — always confirm with podman network inspect before debugging.

You verified name resolution with getent hosts and a real wget http://backend-nginx/ call, configured aliases, and read /etc/resolv.conf to see the Aardvark gateway address. Passing --dns does not always change the nameserver line visible in the file; Aardvark still uses your upstream servers for external domains. --disable-dns removes name resolution while leaving host-style external DNS intact.

When something fails, test container names, external names, and raw IP connectivity separately. Names that work on one network but not another usually mean the containers are not on the same DNS-enabled bridge.


Frequently Asked Questions

1. Why cannot my Podman containers resolve each other by name?

Check podman network inspect and DNSEnabled on the network both containers use. The built-in podman bridge on Podman 5.8 often has DNS disabled, while user-created bridge networks enable Aardvark DNS by default. Containers on different networks or a network created with --disable-dns will not resolve each other by name through Aardvark.

2. What is Aardvark DNS in Podman?

Aardvark DNS is Podman's per-network DNS server for container names and aliases on DNS-enabled bridge networks. On a normal DNS-enabled bridge, it answers container names and forwards other queries upstream. On an --internal network, it resolves container names but does not forward external queries.

3. Why does resolv.conf show a Podman IP after I pass --dns 1.1.1.1?

On DNS-enabled custom networks, Podman points the container at the Aardvark resolver on the bridge gateway. Aardvark forwards non-container queries to the DNS servers you passed with --dns. The custom server may not appear directly in resolv.conf even though it is used for external lookups.

4. Does --disable-dns on a network block all DNS?

No. --disable-dns turns off Podman's container-name DNS plugin for that bridge. External name resolution can still work through normal resolv.conf nameservers inherited from the host. Container-to-container name lookups through Aardvark stop working.

5. Is host.containers.internal the same as Aardvark DNS?

No. host.containers.internal and host.docker.internal are usually added through Podman's managed /etc/hosts entries and host-gateway logic so containers can reach the host. Aardvark resolves other container names on the same DNS-enabled network.
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)