When `ip link` shows no IP but you can ping: diagnosing an absent IPv4 on a bridge interface

I was in the middle of setting up a tiny homelab VM that bridges straight to the host. The guest could ping the gateway just fine, but ip addr show br0 was staring back at me with no inet line. The bridge was up, state UP, yet no IPv4. What’s going on?

1. Distinguish link‑state from IP‑state

ip link only tells you about the link layer. An interface can be physically up and still have no IP if the DHCP client never got a lease or a static config never ran.

ip link show br0
# state UP, no inet

If you’re on a system that uses systemd‑networkd, check the unit status:

systemctl status systemd-networkd

Since kernel 5.15, bridge‑DHCP handling got stricter. If you set DHCP=yes on a bridge but the DHCP server is unreachable, the interface will stay link‑up but without an address.

2. Look at the DHCP client

On most distros the DHCP assignment for bridges comes from dhclient or systemd-networkd. Dig into the logs:

journalctl -u systemd-networkd | grep br0

If you see No DHCPOFFER received, the server is either down or the bridge’s MAC is being blocked. Remember, a bridge inherits the MAC of its first enslaved interface; if that interface is down, the bridge’s MAC can look “unknown” to the DHCP server.

3. Make sure you actually have enslaved ports

A bridge with no enslaved interface is just a virtual NIC that won’t talk to the network. Run:

brctl show br0

You should see at least one member, e.g. eth0 or enp0s3. An empty list means the bridge is effectively a dead‑end; you can’t reach the gateway unless you’re on loopback or a purely virtual network.

4. Netfilter bridge hooks can kill you silently

If you’re forwarding packets with iptables or nftables, the kernel’s bridge hooks might be dropping traffic before the DHCP client even sees it. Check the flag:

sysctl net.bridge.bridge-nf-call-iptables
# 1 means the bridge passes packets through iptables

If it’s 0, packets get dropped early. Enable it:

sysctl -w net.bridge.bridge-nf-call-iptables=1

Persist it with a file like /etc/sysctl.d/99-bridge.conf.

5. Double‑check the gateway’s ARP table

Sometimes the gateway sees the bridge’s MAC but never assigns an IP because the MAC isn’t in its ARP table. On the gateway:

arp -n | grep <bridge-mac>

If nothing shows up, clear the stale entry:

arp -d <bridge-mac>

6. A quick security sanity check

Bridges can be a vector for MAC spoofing if you let untrusted VMs plug in. Lock the bridge’s MAC to a permanent entry:

bridge fdb add <mac> dev br0 permanent

That stops other VMs from impersonating the bridge and potentially snatching an IP from the DHCP server.


Quick checklist

Step Command What to look for
Verify link ip link show br0 state UP
Check DHCP logs `journalctl -u systemd-networkd grep br0`
Enslaved interfaces brctl show br0 At least one enslaved
Netfilter bridge hooks sysctl net.bridge.bridge-nf-call-iptables Should be 1
ARP table `arp -n grep `
MAC lock bridge fdb add <mac> dev br0 permanent Permanent entry

If everything looks good but the bridge still shows no IP, a quick restart of the networking service usually does the trick:

systemctl restart systemd-networkd

or just reboot the VM. In my experience, the most common culprits are a missing enslaved interface or a DHCP client that didn’t get a lease.



See also