Fix Podman Container Cannot Access the Internet

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
Applies to Any Linux host with Podman where containers start but cannot reach external services
Privilege Rootful examples as root; rootless pasta notes where behavior differs
Scope Separating DNS from routing and proxy failures, getent and raw-IP curl tests, --network=none and internal bridge isolation, podman inspect network mode, rootful firewall-cmd --reload impact and podman network reload, netavark backend and ip_forward, podman network inspect, rootless pasta default-route selection, proxy env vars, IPv4 versus IPv6, and a diagnostic matrix. Does not cover full Aardvark DNS, host-access procedures, general firewall administration, or port publishing.
Related guides Create and manage Podman networks
Podman networking modes

A container that starts cleanly can still fail every outbound request. Before you change DNS servers or restart Podman, run three quick tests inside the container:

  • name lookup
  • raw IP connectivity
  • routing table (ip route)

Those three results tell you whether the problem is DNS, missing routes, firewall rules, or an intentionally isolated network mode.

IMPORTANT
This article restores external Internet connectivity. Container-name resolution and Aardvark DNS live in Podman DNS and name resolution. Reaching the host from a container — especially the rootless pasta main-IP gotcha — is covered in Access the host from a container.

Separate DNS, routing, and application errors

Run these three checks inside the failing container before you pick a fix.

DNS test

Resolve a hostname from inside the container:

bash
podman exec CONTAINER getent hosts example.com

Sample output when DNS works on the lab host:

output
104.20.23.154   example.com
172.66.147.243  example.com

When DNS is broken, getent may print nothing. A name-based HTTP request shows resolver failure:

bash
podman exec CONTAINER curl -sS --connect-timeout 5 http://example.com
output
curl: (6) Could not resolve host: example.com

Raw IP connectivity test

Bypass DNS and hit a known address:

bash
podman exec CONTAINER curl -sS -o /dev/null -w 'HTTP %{http_code}\n' --connect-timeout 5 http://1.1.1.1

Sample output on a healthy rootful container:

output
HTTP 301

Cloudflare returns 301 for bare HTTP to 1.1.1.1 — the status code confirms TCP connectivity even when the body is a redirect page.

Route test

Inspect routes when the image includes iproute:

bash
podman exec CONTAINER ip route

On the default rootful bridge, the lab container shows a default gateway:

output
default via 10.88.0.1 dev eth0 proto static metric 100
10.88.0.0/16 dev eth0 proto kernel scope link src 10.88.3.226

If name lookup fails but raw IP works, treat it as DNS — not routing. If there is no default line, investigate network mode before you touch resolvers.


curl: (6) Could not resolve host

When raw IP connectivity succeeds but names fail, the branch is DNS:

  • /etc/resolv.conf inside the container
  • upstream resolver reachability from the container network
  • custom --dns / --dns-search on podman run
  • resolver configuration

Point container-name and alias lookups to Podman DNS and name resolution. This article stays on restoring outbound Internet access.

To reproduce a resolver-only failure on the lab host, pass an unreachable DNS server:

bash
podman run --rm --dns 127.0.0.1 registry.access.redhat.com/ubi9/ubi-minimal:latest getent hosts example.com

getent exits with no output while routing still works. Confirm with raw IP:

bash
podman run --rm --dns 127.0.0.1 registry.access.redhat.com/ubi9/ubi-minimal:latest curl -sS -o /dev/null -w 'HTTP %{http_code}\n' --connect-timeout 5 http://1.1.1.1

Sample output:

output
HTTP 301

Names fail; IPs still reach the Internet — fix DNS configuration, not the bridge.


No route or no outbound connectivity

Deliberate isolation produces routing failures. With --network=none:

bash
podman run --rm --network=none registry.access.redhat.com/ubi9/ubi-minimal:latest curl -sS --connect-timeout 3 http://1.1.1.1

Sample output:

output
curl: (7) Couldn't connect to server

--network=none gives the container no network connectivity. ip route normally has no usable routes — that is expected. Assign a network if the workload needs outbound access.

An internal bridge still assigns an IP but blocks outbound forwarding:

bash
podman network create --internal int-route-demo

Inspect routes on a container attached to that network:

bash
podman run --rm --network int-route-demo docker.io/library/alpine:3.20 ip route

Sample output:

output
10.89.0.0/24 dev eth0 proto kernel scope link src 10.89.0.2

There is no default via line. Outbound curl fails on the same network:

bash
podman run --rm --network int-route-demo docker.io/library/alpine:3.20 curl -sS --connect-timeout 3 http://1.1.1.1
output
curl: (7) Couldn't connect to server

Internal networks are working as designed — do not treat them as broken Internet.


Check the container network mode

See which network attachments Podman recorded:

bash
podman inspect --format '{{json .NetworkSettings.Networks}}' CONTAINER

Sample output for a container on the default podman bridge:

output
{"podman":{"Gateway":"10.88.0.1","IPAddress":"10.88.3.217","IPPrefixLen":16,"MacAddress":"4a:3f:40:96:d8:08","NetworkID":"2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9","Aliases":["23e1ff4e3926"]}}

Modes that commonly block external Internet by design:

  • --network=none
  • --internal bridge networks
  • custom networks created without a default route, such as with no_default_route=true

If isolation is intentional, change the application design — not the firewall — to reach external services.


Rootful: firewall-cmd --reload can break running containers

Rootful Netavark bridge networking installs firewall rules when a container starts. firewall-cmd --reload can remove those rules while containers keep running — outbound NAT and forwarding stop working even though the container process is still up.

Workflow on the lab host:

  1. Start a long-running container on the default bridge.
  2. Confirm outbound access.
  3. Run firewall-cmd --reload.
  4. Test again.
  5. Run podman network reload if access broke.

Create a test container:

bash
podman run -d --name nettest-curl registry.access.redhat.com/ubi9/ubi-minimal:latest sleep 3600

Verify egress before any firewall change:

bash
podman exec nettest-curl curl -sS -o /dev/null -w 'HTTP %{http_code}\n' --connect-timeout 5 http://1.1.1.1

Sample output:

output
HTTP 301

Reload firewalld:

bash
firewall-cmd --reload

Sample output:

output
success

Retest the same curl command. On this lab host egress survived the reload — firewalld zone state and existing rules vary by machine. Upstream Podman documentation still documents the failure mode: containers that worked before reload suddenly cannot reach external addresses until network rules are recreated.

When you see that regression, symptoms often look like a routing or timeout failure rather than DNS — getent may still resolve names while curl to the same host hangs or returns Connection timed out. That pattern after a firewall change is the signal to run podman network reload, not to replace resolvers.


Fix with podman network reload

Recreate Netavark firewall integration for one container:

bash
podman network reload nettest-curl

Sample output on the lab host:

output
[WARN  netavark::firewall::firewalld] Error removing subnet 10.88.0.0/16 from firewalld trusted zone: org.fedoraproject.FirewallD1.Exception: UNKNOWN_SOURCE: '10.88.0.0/16' is not in any zone
23e1ff4e3926c16c7cf46a18c364d03cfd12fbef94360f956038aa576bc49e31

The warning is noisy but the command succeeded — it printed the container ID. Retest connectivity:

bash
podman exec nettest-curl curl -sS -o /dev/null -w 'HTTP %{http_code}\n' --connect-timeout 5 http://1.1.1.1

Refresh every running container after a host-wide firewall change:

bash
podman network reload --all

podman network reload recreates firewall rules for Netavark-managed rootful networks. It is the documented recovery step after firewall-cmd --reload — not a substitute for fixing DNS or internal network isolation.


Do not use network reload for rootless pasta

The firewall-reload regression applies to rootful Netavark bridge rules managed through firewalld. Rootless default pasta does not depend on that same rootful rule path.

When rootless Internet fails:

  • check host default route selection for pasta
  • read Rootless Podman networking for pasta interface options
  • verify the host itself reaches the destination

Running sudo podman network reload against a rootless pasta container is not the first fix.


Check host IP forwarding for rootful bridge mode

Rootful bridge NAT expects IPv4 forwarding on the host:

bash
sysctl net.ipv4.ip_forward

Sample output on the lab host:

output
net.ipv4.ip_forward = 1

Confirm your network backend before you change sysctl:

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

Sample output:

output
netavark

RHEL 10.2 with Podman 5.8.2 uses Netavark — not legacy CNI plugins. Only enable forwarding when bridge routing actually needs it and your security policy allows it.


Inspect the Podman network object

Pull subnet, gateway, and isolation flags from the network definition:

bash
podman network inspect podman

Sample output (trimmed):

output
[
     {
          "name": "podman",
          "driver": "bridge",
          "network_interface": "podman0",
          "subnets": [
               {
                    "subnet": "10.88.0.0/16",
                    "gateway": "10.88.0.1"
               }
          ],
          "internal": false,
          "dns_enabled": false
     }
]

internal: true means no outbound Internet on that bridge. On the built-in podman network, two DNS facts matter:

  • dns_enabled: false is normal — external lookups still use resolv.conf
  • Container-name DNS needs a user-defined network with DNS enabled

See Podman DNS and name resolution for that split.


Rootless pasta: default route and interface selection

Pasta maps outbound traffic through the host default route and main interface. On the host:

bash
ip route show default

Inside a rootless pasta container, routes mirror the host layout. When the host has no default route, or several competing interfaces, pasta may not pick the interface you expect. Documented pasta options — such as binding to a specific interface — live in Rootless Podman networking. This article does not duplicate full pasta tuning.


Rootless pasta main-IP is not “no Internet”

Pasta copies the host main IP into the container namespace. Failing to curl the host at that same address from inside the container is a host-access scenario — external sites may work fine.

If curl https://example.com succeeds but curl http://HOST_MAIN_IP:PORT fails, open Access the host from a container instead of resetting networks.


Proxy environment variables

Corporate egress may require HTTP proxies. List environment variables Podman injected:

bash
podman inspect --format '{{range .Config.Env}}{{println .}}{{end}}' CONTAINER

When outbound access requires a proxy, direct requests from the container may fail even though the host works. Compare HTTP_PROXY, HTTPS_PROXY, and NO_PROXY inside the container with the host configuration. This article does not walk through proxy server configuration.


Host firewall and forwarded traffic

Rootful bridge egress depends on Netavark-generated rules inside firewalld or nftables. Inspect active zones:

bash
firewall-cmd --get-active-zones

Do not disable the host firewall as a generic fix. After legitimate firewall changes, podman network reload is the Podman-native recovery step for affected containers.


IPv4 works but IPv6 fails

Test each family separately:

bash
podman exec CONTAINER curl -4 -sS -o /dev/null -w 'v4 %{http_code}\n' --connect-timeout 5 http://1.1.1.1

Repeat the same check over IPv6:

bash
podman exec CONTAINER curl -6 -sS -o /dev/null -w 'v6 %{http_code}\n' --connect-timeout 5 http://[2606:4700:4700::1111]/

Mixed IPv6 breakage is not a complete Internet outage when IPv4 paths work. Check whether the network has ipv6_enabled and whether the host routes IPv6.


Diagnostic matrix

Symptom Likely branch First step
Names fail, raw IP works DNS Fix resolvers, --dns, upstream reachability; see DNS guide for names
No default route in ip route Network mode / internal bridge Check --network and internal flag
Broke right after firewall-cmd --reload Dropped Netavark rules podman network reload or --all
Rootless pasta, external OK, host main IP fails Host access, not Internet host.containers.internal guide
Rootful bridge, no outbound at all Forwarding or firewall ip_forward, network reload, zone rules
Only proxy-gated URLs fail Proxy env Compare podman inspect env to host
v4 OK, v6 fails IPv6 routing or disabled network curl -4 / curl -6, ipv6_enabled

Troubleshooting

Symptom Likely cause Fix
Could not resolve host Bad DNS server or search domain Fix --dns / resolv.conf; test with getent
getent empty, curl to IP works DNS only Do not restart bridge — fix resolver path
Couldn't connect on --network=none No network connectivity Attach a network
Couldn't connect on internal network No default route by design Use non-internal network for Internet
Worked until firewall reload Netavark rules removed podman network reload
Rootless external OK, host IP fails pasta main-IP loop Host-access guide, not this article
ip_forward = 0 on bridge host Forwarding disabled Enable only when policy allows
Container names fail, Internet OK Aardvark / network DNS DNS guide

References


Summary

A Podman container with no Internet is usually a DNS problem, a routing problem, or a firewall problem — and the three are easy to confuse. Run getent or name-based curl, then raw IP curl, then ip route inside the container before you change global DNS or restart Podman.

--network=none and internal bridge networks block outbound access on purpose. Rootful Netavark bridges can lose connectivity after firewall-cmd --reload when Netavark-managed rules disappear; podman network reload recreates those rules for one container or with --all. That path is for rootful bridge networking — not rootless pasta.

When names fail but IPs work, fix DNS and read the dedicated DNS guide for container-name resolution. When external sites work but the host main IP does not inside a rootless container, that is host access — not Internet outage. Use the diagnostic matrix to pick the branch, then open the linked guide for DNS, pasta, or host connectivity detail.


Frequently Asked Questions

1. Why can my Podman container ping an IP but not resolve domain names?

Routing works but DNS does not. Test curl or getent against a raw IP first, then check resolv.conf, podman run --dns, and upstream resolver reachability. Container-name DNS through Aardvark is a separate topic from external Internet lookups.

2. Does firewall-cmd --reload break Podman container Internet access?

On rootful Netavark bridge networks it can. Reload may remove Netavark-managed firewall rules while containers keep running. Run podman network reload on affected containers or podman network reload --all. Rootless pasta does not use the same rootful firewall-rule path.

3. What is the difference between --network=none and an internal bridge?

none gives the container no network connectivity. An internal bridge assigns an IP and allows container-to-container traffic on that network but blocks outbound Internet forwarding. Both can fail external curl tests for different reasons.

4. Should I use podman network reload for rootless pasta failures?

No. network reload recreates rootful Netavark firewall integration. Rootless default pasta failures need pasta-specific diagnosis such as host default route selection. See rootless Podman networking for that path.

5. Why does curl to the host main IP fail in rootless Podman but external sites work?

pasta copies the host main interface address into the container namespace. Reaching that same address from inside the container is a host-access problem, not external Internet failure. Use host.containers.internal instead of the shared main IP.
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)