host.containers.internal unreachable from rootless bridge containers: shared rootless-netns pasta missing --map-host-loopback
Issue Description
Podman writes 169.254.1.2 host.containers.internal into every container's
/etc/hosts and passes --map-guest-addr=169.254.1.2 to the shared
rootless-netns pasta, but never passes the outbound counterpart
--map-host-loopback=169.254.1.2. The host.containers.internal contract is
half-wired:
- inbound (host → container at 169.254.1.2): handled by
--map-guest-addr
- outbound (container → host via 169.254.1.2): not handled — packets to
169.254.1.2 fall through to the default route and die
For rootless bridge containers (the common case for any custom network) this
makes host.containers.internal unreachable, despite podman's own
/etc/hosts entry promising it works.
Reproducer
# host: any TCP service on loopback
python3 -m http.server 9100 &
# fresh rootless container on a podman-created bridge network
podman run --rm --network=podman docker.io/alpine \
wget -qO- --timeout=3 http://host.containers.internal:9100/
# actual: wget: download timed out
# expected: directory listing from the python server
/etc/hosts inside the container correctly contains:
169.254.1.2 host.containers.internal host.docker.internal
The shared rootless-netns pasta launched by podman has:
/usr/bin/pasta --config-net --pid ... --dns-forward 169.254.1.1 \
-t none -u none -T none -U none --quiet \
--netns /run/user/$UID/containers/networks/rootless-netns/rootless-netns \
--map-guest-addr 169.254.1.2
--map-host-loopback is missing. pasta has full support for the flag; podman
just doesn't pass it.
Workaround (confirms the root cause)
# ~/.config/containers/containers.conf
[network]
pasta_options = ["--map-host-loopback=169.254.1.2"]
Then stop all rootless containers using the shared rootless-netns so the
long-running pasta exits, and let the next container spawn re-launch pasta
with the new argv. Verify:
ps -eo cmd | grep -F /usr/bin/pasta
# /usr/bin/pasta --config-net --map-host-loopback=169.254.1.2 ... --map-guest-addr 169.254.1.2
host.containers.internal:<port> then reaches host services from bridge
containers as the /etc/hosts entry implies.
Suggested Fix
In the rootless-netns pasta launcher
(containers/common/libnetwork/pasta/pasta_linux.go createPastaArgs), add
--map-host-loopback symmetrically with the existing --map-guest-addr
default. The two are both halves of the same host.containers.internal
contract and should never be split.
Rough sketch:
if len(mapGuestAddrIPs) == 0 {
cmdArgs = append(cmdArgs, mapGuestAddrOpt, mapGuestAddrIpv4)
mapGuestAddrIPs = append(mapGuestAddrIPs, mapGuestAddrIpv4)
}
// outbound counterpart: without this the /etc/hosts entry podman writes for
// host.containers.internal is unreachable from bridge containers
if !containsArg(cmdArgs, "--map-host-loopback") {
cmdArgs = append(cmdArgs, "--map-host-loopback", mapGuestAddrIpv4)
}
The IP picked should track host_containers_internal_ip so a custom contract
IP stays consistent across /etc/hosts, --map-guest-addr, and
--map-host-loopback.
Environment
| component |
version |
| podman |
5.8.2 |
| netavark |
1.17.2 |
| pasta |
2026_05_07.1afd4ed |
| kernel |
7.0.6-1-cachyos |
| distro |
CachyOS (Arch-based) |
Related Issues
host.containers.internalunreachable from rootless bridge containers: shared rootless-netns pasta missing--map-host-loopbackIssue Description
Podman writes
169.254.1.2 host.containers.internalinto every container's/etc/hostsand passes--map-guest-addr=169.254.1.2to the sharedrootless-netns pasta, but never passes the outbound counterpart
--map-host-loopback=169.254.1.2. Thehost.containers.internalcontract ishalf-wired:
--map-guest-addr169.254.1.2fall through to the default route and dieFor rootless bridge containers (the common case for any custom network) this
makes
host.containers.internalunreachable, despite podman's own/etc/hostsentry promising it works.Reproducer
/etc/hostsinside the container correctly contains:The shared rootless-netns pasta launched by podman has:
--map-host-loopbackis missing. pasta has full support for the flag; podmanjust doesn't pass it.
Workaround (confirms the root cause)
Then stop all rootless containers using the shared rootless-netns so the
long-running pasta exits, and let the next container spawn re-launch pasta
with the new argv. Verify:
host.containers.internal:<port>then reaches host services from bridgecontainers as the
/etc/hostsentry implies.Suggested Fix
In the rootless-netns pasta launcher
(
containers/common/libnetwork/pasta/pasta_linux.gocreatePastaArgs), add--map-host-loopbacksymmetrically with the existing--map-guest-addrdefault. The two are both halves of the same
host.containers.internalcontract and should never be split.
Rough sketch:
The IP picked should track
host_containers_internal_ipso a custom contractIP stays consistent across
/etc/hosts,--map-guest-addr, and--map-host-loopback.Environment
Related Issues
(closed). Same user-visible symptom; the discussion settled on
"rootlessport vs pasta" as a design trade-off, but that frame only applies
to inbound port mapping. The outbound path for bridge containers actually
goes through pasta already — the workaround above is direct proof.
(open). Same area; same broken contract.
container connected to a bridge network (closed as expected). About
inbound port mapping only; doesn't cover the outbound side this issue is
about.
orthogonal: that's about inbound. This issue is one missing flag on the
outbound side that doesn't require any redesign.