DHCP troubleshooting — lease exhaustion, conflict detection, relay loops, silent failures
What you'll learn
- Diagnose lease exhaustion in DHCPv4 and DHCPv6
- Recognise IP conflict detection and the DECLINE failure mode
- Identify DHCP relay loops and giaddr mismatches
- Apply a systematic DHCP diagnostic flow from symptom to root cause
Prerequisites
Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15
DHCP failures on production routing estates surface in two ways: hosts cannot obtain a lease (no connectivity at all), or hosts obtain a lease but with the wrong parameters (no Internet, no DNS, no off-net routing). The diagnostic flow is the same in both cases: capture the wire, identify which message is missing, and trace the failure back to its source.
This lesson is the diagnostic reference for DHCP on VyOS 1.5 LTS. It covers the common failure modes (lease exhaustion, IP conflict detection, relay loops, giaddr mismatches, server bound to the wrong interface, option 82 mishandling), the diagnostic flow for each, and the operational commands that reveal the state.
The diagnostic flow
flowchart TD
A["Symptom<br/>host has no address<br/>or wrong parameters"] --> B{"Capture the wire"}
B --> C["tcpdump port 67 / 68"]
C --> D{"DISCOVER has<br/>no OFFER?"}
D -- "yes" --> E["Server is not<br/>listening on this segment"]
D -- "no" --> F{"OFFER has<br/>no ACK?"}
F -- "yes" --> G["Server cannot<br/>allocate from pool"]
F -- "no" --> H{"ACK has wrong<br/>parameters?"}
H -- "yes" --> I["Option set is<br/>misconfigured"]
H -- "no" --> J["DHCP is fine<br/>issue is downstream<br/>(firewall, NAT, DNS)"]
The flow is: capture, identify the missing message, trace the failure. The diagnostic commands are show dhcp server leases, show dhcp server statistics, tcpdump, and arp -an. The operator who reaches for complex explanations first misses the simple answers.
Failure mode 1 — Lease exhaustion
Symptom: new hosts cannot obtain a lease. Existing hosts continue to function (their leases are still valid). show dhcp server leases shows the pool at 100% utilisation.
Diagnostic:
vyos@R1:~$ show dhcp server statistics
Packets received: 12345
Packets sent: 12340
Requests received: 1234
Requests ignored: 5
Naks sent: 5
vyos@R1:~$ show dhcp server leases
(... pool at 100% utilisation ...)
The “Requests ignored” and “Naks sent” counters indicate requests the server cannot satisfy. The most common cause: the pool is exhausted.
flowchart TD
A["New host broadcasts DISCOVER"] --> B{"Pool has<br/>free addresses?"}
B -- "yes" --> C["OFFER with pool address"]
B -- "no" --> D["Server replies with<br/>DHCPOFFER (best-effort)<br/>but REQUEST is NAKed"]
D --> E["Host retries<br/>eventually gives up"]
The fix depends on the cause:
- Pool too small for the number of hosts. Extend the range (
range 0 stop '<higher>') or add a second range. - Leases not reclaimed. Old leases remain in the database even after hosts have left the network. Shorten the lease time so leases expire faster.
- Reservation outside dynamic range. If reservations are inside the dynamic range, the dynamic range effectively shrinks.
Failure mode 2 — IP conflict detection (DECLINE)
Symptom: a host broadcasts DHCPDISCOVER, receives DHCPOFFER, sends DHCPREQUEST, but then immediately sends DHCPDECLINE.
Diagnostic:
vyos@R1:~$ tcpdump -i eth1.10 -n port 67 or port 68 -vv
12:00:01.234 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from aa:bb:cc:dd:ee:f0
Option 53, length 1: DHCP Discover
12:00:01.236 IP 192.0.2.1.67 > 192.0.2.50.68: BOOTP/DHCP, Reply
Option 53, length 1: DHCP Offer
yiaddr 192.0.2.50
12:00:01.245 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from aa:bb:cc:dd:ee:f0
Option 53, length 1: DHCP Request
12:00:01.247 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from aa:bb:cc:dd:ee:f0
Option 53, length 1: DHCP Decline
Option 56, length 7: Server-Identifier, Server Message
Option 50, length 4: Requested IP Address 192.0.2.50
The DECLINE is sent by the host after it ARPs the offered address and finds that another host is already using it. The host tells the server “I cannot use this address; please give me another.”
Common causes:
- Two DHCP servers on the same subnet. Both servers allocate addresses; they conflict. The fix: identify the rogue server and decommission it, or set
authoritativeon the correct server. - Static host at the offered address. A host has a static IP that conflicts with the pool range. The fix: move the static host out of the pool range.
- Stale reservation. A reservation’s MAC was changed but the old host still has the lease. The fix: clean up the old lease.
Failure mode 3 — Relay loop
Symptom: hosts on either side of two relays see no leases. The diagnostic is the same as relay configuration problems but with a specific signal: hop count incrementing in the capture.
Diagnostic:
vyos@R1:~$ tcpdump -i eth0 -n port 67 or port 68 -vv
12:00:01.234 IP 203.0.113.1.67 > 203.0.113.2.67: BOOTP/DHCP, Request
giaddr 203.0.113.1
hops 1
Option 53, length 1: DHCP Discover
12:00:01.236 IP 203.0.113.2.67 > 203.0.113.1.67: BOOTP/DHCP, Request
giaddr 203.0.113.2
hops 2 <-- incremented
Option 53, length 1: DHCP Discover
12:00:01.245 IP 203.0.113.1.67 > 203.0.113.2.67: BOOTP/DHCP, Request
giaddr 203.0.113.1
hops 3 <-- incremented
Option 53, length 1: DHCP Discover
The hop count is incrementing each time the packet traverses a relay. After 16 hops the packet is dropped.
The fix: break the loop by pointing one relay’s upstream at the actual server (not at the other relay).
Failure mode 4 — giaddr mismatch
Symptom: the relay’s packets reach the server, but the server never replies. The captures show DHCPDISCOVER with giaddr set, but no DHCPOFFER.
Diagnostic:
vyos@R1:~$ tcpdump -i eth0 -n port 67 or port 68 -vv -c 1
12:00:01.234 IP 203.0.113.1.67 > 203.0.113.53.67: BOOTP/DHCP, Request
giaddr 203.0.113.1
hops 1
Option 53, length 1: DHCP Discover
The packet reaches the server with giaddr=203.0.113.1, but the server has no subnet that contains 203.0.113.1. The server cannot match the request to a subnet; it silently drops the request.
The fix: ensure the relay’s upstream-interface address is in a subnet the server recognises. The operator may need to add a subnet declaration on the server for the relay’s address, or change the relay to use a different address.
Failure mode 5 — Server bound to wrong interface
Symptom: hosts on the LAN broadcast DHCPDISCOVER but receive no DHCPOFFER. The server configuration is correct.
Diagnostic:
vyos@R1:~$ show configuration service dhcp-server
service dhcp-server {
shared-network-name LAN1 {
subnet 192.0.2.0/24 {
...
}
}
}
vyos@R1:~$ show configuration interfaces ethernet eth1 vif 10
interfaces ethernet eth1 vif 10 {
address 192.0.2.1/24
# NOTE: no dhcp-server directive
}
The service dhcp-server defines the shared-network, but no interface has dhcp-server LAN1. The Kea listener is not active on any interface.
The fix: bind the server with set interfaces ethernet eth1 vif 10 dhcp-server LAN1 and commit.
Failure mode 6 — Option 82 mishandling
Symptom: the relay is configured and forwarding, but the host does not take the offered lease. The capture shows DHCPOFFER arriving at the relay, but the host never sends DHCPREQUEST.
Diagnostic:
vyos@R1:~$ tcpdump -i eth1.10 -n port 67 or port 68 -vv
12:00:01.236 IP 192.0.2.1.67 > 192.0.2.50.68: BOOTP/DHCP, Reply
Option 53, length 1: DHCP Offer
yiaddr 192.0.2.50
Option 82, length 18: Relay-Agent-Information
Circuit-Id eth1.10
Remote-Id R1-EDGE
12:00:01.245 # NO REQUEST from client
The server’s DHCPOFFER includes option 82, but the host discards the offer because option 82 is malformed or because the host does not recognise it. This is the “option 82 dropped by server” failure mode.
The fix depends on the cause:
- Server dropping option 82: configure the server to accept (forward or trust) option 82.
- Relay inserting malformed option 82: reconfigure the relay with the correct circuit-id and remote-id.
- Host not handling option 82: this is rare on modern hosts; usually the issue is the server.
A complete diagnostic flow
# Step 1: Symptom (host has no address or wrong parameters)
# Step 2: Capture the wire on the affected LAN interface
tcpdump -i eth1.10 -n port 67 or port 68 -vv -w /tmp/dhcp.pcap &
# Run for 30 seconds while a host attempts DHCP
# Step 3: Inspect the captures
# Is there DHCPDISCOVER? (yes — host is broadcasting)
# Is there DHCPOFFER? (no — server not responding)
# If yes: is there DHCPREQUEST? (no — host doesn't accept offer)
# If yes: is there DHCPACK? (no — server can't allocate)
# Step 4: Check the lease file
show dhcp server leases
# Pool utilisation? Lease state?
# Step 5: Check the relay (if applicable)
show dhcp relay status
show dhcp relay statistics
# Packets forwarded? Replies received?
# Step 6: Check the upstream
# Is the server reachable? Is the firewall blocking UDP 67?
# Step 7: Apply the fix based on the diagnosis
# (modify the configuration; commit; re-test)
Production failure modes
Lease exhaustion in a quiet network
A network that has been stable for months suddenly cannot allocate new leases. The lease file shows old leases still active (the hosts are gone but the leases haven’t expired). The fix: shorten the lease time; the next lease cycle reclaims the stale leases.
Reservations silently broken
A printer is replaced; the new printer has a different MAC; the old reservation sits in the configuration. The new printer falls through to the dynamic pool. The fix: update the static-mapping’s MAC and check the rest of the static-mapping list for similar issues.
Server on wrong interface after a config refactor
A bulk configuration change moves the DHCP server from eth1.10 to eth1.20 (VLAN renumbering). The operator forgets to update the interface binding. The server has the configuration but no listener on eth1.10. The fix: verify every interface binding after a VLAN renumber.
Rollback
# Capture the diagnostic output
show dhcp server leases | save /tmp/vyos-dhcp-leases-$(date +%s).txt
show dhcp server statistics | save /tmp/vyos-dhcp-stats-$(date +%s).txt
tcpdump -i eth1.10 -n port 67 or port 68 -vv -w /tmp/vyos-dhcp-cap-$(date +%s).pcap
# Roll back to a previous configuration
configure
load /tmp/vyos-dhcp-backup-$(date +%s).conf
commit
save
The rollback restores the previous DHCP configuration. The captures are the operator’s evidence for the post-incident review.
Production discipline
Cross-course references
XLVI-VyOS-DHCP(vyos-xlvi-01-dhcp-server,vyos-xlvi-02-dhcp-static-mapping,vyos-xlvi-03-dhcp-relay,vyos-xlvi-04-dhcpv6-server) cover the configuration this lesson diagnoses.LII-VyOS-Troubleshootcovers the wider diagnostic methodology.XLVIII-VyOS-Logging(vyos-xlviii-01-local-logging) covers the syslog export the DHCP server should emit for forensic analysis.
Quiz
Knowledge check · 4 questions
Q1. What does a DHCPv4 DECLINE message from a host indicate?
Q2. When a DHCPv6 server cannot allocate from the pool, it silently drops the request without replying.
Q3. An operator has a DHCPv4 server on the LAN. Hosts broadcast DHCPDISCOVER and receive DHCPOFFER, but never send DHCPREQUEST. tcpdump shows the OFFER arriving at the host with an unexpected option 82. What is the issue and what is the fix?
The relay inserts option 82 into the OFFER. The server is configured to forward option 82. The host receives the OFFER with option 82 and discards it because the host's DHCP client does not recognise the option 82 encoding. The host never sends DHCPREQUEST. This is the 'option 82 mishandling' failure mode.
Q4. An operator observes that new hosts on the LAN cannot obtain a lease. show dhcp server leases shows the pool at 100% utilisation. show dhcp server statistics shows NAKs incrementing. What is the fix?
The DHCPv4 pool is exhausted. The server is sending DHCPOFFER (best-effort) and then DHCPNAK on the REQUEST because the pool is full. New hosts cannot obtain a lease. Existing hosts continue to function because their leases are still valid (until they expire). The most common causes: pool too small for the number of hosts, leases not being reclaimed (lease time too long), or reservations inside the dynamic range.
Passing score: 75%. Answers are checked in this browser.