Everyone already online is fine. But every device that joins now — a phone off Wi-Fi and back, a laptop at the start of the day — gets a useless 169.254 address and reaches nothing. The network is not down; the pool of addresses to hand out is empty. Someone is taking them all, or there were never enough, or a second DHCP server is answering first.
DHCP hands out addresses from a finite pool, each on a lease that lasts until it expires or is renewed. While a device holds a lease it keeps working regardless of the pool state — which is exactly why this failure is so confusing: everyone already connected is fine, and only the people joining are broken. The pool is empty, so a new DISCOVER gets no OFFER, and the client falls back to a link-local 169.254 address that reaches nothing.
There are three very different causes, and telling them apart is the whole job: a starvation attack deliberately drains the pool with spoofed requests; an undersized pool simply has fewer addresses than devices that show up; and a rogue DHCP server answers faster than yours and hands out a broken or hostile configuration. Same symptom, three fixes.
01
Leases keep the already-connected alive while the pool drains. A new client asks, there is nothing to give, and it is stranded on a 169.254 address.
Because the already-connected stay online, the first reports are confusing: “the internet is down” from someone whose neighbour is streaming happily. The tell is that it is always the new arrival — a device that just roamed, rebooted, or walked in the door — and often clusters at a busy time of day when the most devices are present at once.
02
Before you fix it, decide which of the three it is — the fixes do not overlap.
| Cause | Tell it apart by… |
|---|---|
| Starvation attack | The lease list is full of random, meaningless MAC addresses — far more than real devices. A host is spraying spoofed DISCOVERs. |
| Undersized pool | The lease list is full of real devices, and the count is simply near the pool size. Common on guest Wi-Fi with a /24 and long leases. |
| Rogue DHCP server | Clients get an address, but the wrong gateway/DNS — someone plugged a home router into a wall port and it answers faster than yours. |
03
New devices broken, old ones fine, clustered in time — and, for the rogue case, a wrong gateway rather than none.
| What you see | What it tells you |
|---|---|
| New devices get 169.254.x.x (APIPA) | No OFFER arrived — the pool is empty (starvation or undersized). |
| Already-connected devices unaffected | They hold valid leases; the fault is only at acquisition. |
| Worst at the busiest hour | Peak device count meets a pool that cannot cover it — points at undersized. |
| Clients get an address but no internet | Wrong gateway/DNS — a rogue DHCP server won the race. |
04
Size the pool for the real peak, shorten leases where churn is high, and use DHCP snooping to kill both starvation and rogue servers at layer 2.
For an undersized pool, size it to peak device count with headroom and shorten the lease where devices come and go (guest Wi-Fi does not need a 24-hour lease — two hours frees addresses fast). For starvation and rogue servers, the layer-2 tools are the answer: DHCP snooping trusts only the port your real server is on, drops server replies from anywhere else (rogue), and rate-limits/port-secures the edge so one host cannot spray thousands of spoofed requests (starvation).
# guest pool sized for peak + short lease so addresses recycle fast
/ip pool set p-guest ranges=10.20.20.10-10.20.23.254
/ip dhcp-server set d-guest lease-time=2hip dhcp snooping ip dhcp snooping vlan 20 interface Gi1/0/48 description uplink to the real DHCP server ip dhcp snooping trust interface range Gi1/0/1 - 47 ip dhcp snooping limit rate 15 ! cap DISCOVERs per second (anti-starvation) ! untrusted ports: server replies (OFFER/ACK) from here are dropped = no rogue
The RouterOS equivalent of snooping is add-arp=yes with DHCP alerts and bridge port controls; the key idea is identical — only the real server’s port may send DHCP offers, and edge ports are rate-limited.
The classic rogue DHCP server is not an attacker — it is a staff member’s home router or a travel AP plugged into a wall port “to get more sockets,” happily handing out 192.168.1.x with its own gateway. DHCP snooping stops it cold, but the lasting fix is segmentation and port security so an unmanaged device in a wall jack cannot speak for the network at all.
05
Look at the lease list. Random MACs mean starvation; real MACs near the pool size mean undersized; a competing OFFER means a rogue.
# RouterOS: how full is the pool, and are the MACs real or random? /ip dhcp-server lease print count-only /ip dhcp-server lease print where status=bound # listen for a second DHCP server answering (rogue): capture OFFERs on the LAN /tool sniffer quick port=67,68 # host side: see every DHCP server that replies to a probe sudo nmap --script broadcast-dhcp-discover
If the lease list is full of nonsense MAC addresses, you are being starved — rate-limit and port-secure the edge. If it is full of real devices at the pool ceiling, grow the pool and shorten the lease. If a probe gets two OFFERs, find and unplug the rogue, then turn on snooping so it can never happen again.
Takeaways
DHCP exhaustion has three very different causes and three different fixes. I tell starvation from an undersized pool from a rogue server, and lock the first and third out with snooping and port security.
Book a Discovery Call →