Skip to content

DHCPACK and DHCPNAK

A Request only asks the server to confirm something it already proposed, or something the client already believes it holds. The server has exactly two ways to answer that ask, and they aren't a spectrum — it's a hard yes or a hard no, with nothing in between.

DHCPACK: the lease actually starts here

DHCPACK is the message that finally makes an address usable. Everything before it — Discover, Offer, even Request — was negotiation; nothing was actually bound to the client until this arrives.

sudo tcpdump -i eth0 -n -v port 67 or port 68
12:00:01.314552 IP (tos 0x10, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 328)
    192.168.1.1.67 > 255.255.255.255.68: BOOTP/DHCP, Reply, length 300, xid 0x3d1e2f8a, Flags [none]
      Your-IP 192.168.1.42
      Client-Ethernet-Address 08:00:27:4e:66:a1
      Vendor-rfc1048 Extensions
        Magic Cookie 0x63825363
        DHCP-Message Option 53, length 1: ACK
        Server-ID Option 54, length 4: 192.168.1.1
        Lease-Time Option 51, length 4: 86400
        Subnet-Mask Option 1, length 4: 255.255.255.0
        Default-Gateway Option 3, length 4: 192.168.1.1
        Domain-Name-Server Option 6, length 8: 192.168.1.1,8.8.8.8

The shared xid, 0x3d1e2f8a, closes out the same attempt that opened with the Discover two articles back — one transaction ID, four packets, from a blank slate to a working configuration. The options here largely repeat what the Offer already proposed; an Acknowledge isn't the moment new terms get introduced, it's the moment the terms already on the table become binding. The client moves to BOUND, and this is the point at which ipconfig /all's Lease Obtained timestamp gets set.

One more check before the address is trusted

RFC 2131 recommends that a client probe its newly confirmed address before actually using it — specifically, with an ARP request for its own new address, the same gratuitous ARP mechanism the ARP article's duplicate-address-detection section already covers in full. If another device on the segment answers claiming that address, the client has caught a conflict — two devices about to share one IP — before it ever sent a single packet under that address. When this happens, the client sends DHCPDECLINE back to the server, refusing the offered address and forcing the whole exchange back to INIT to start over with a different one. This doesn't come up often in practice, since a well-run DHCP pool shouldn't be handing out addresses already in use, but it's the safety check that catches it when a pool has drifted out of sync with reality — a statically configured device sitting inside a range the DHCP server also thinks it owns, for instance.

DHCPNAK: a hard no, not a retry hint

DHCPNAK tells the client its Request can't be honored, for any of a few distinct reasons: the requested address is no longer available, or — specific to the INIT-REBOOT path the first article in this group introduced — the server can tell from context that the client is asking for an address that doesn't belong on the network it's currently connected to. A DHCPNAK always sends the client back to INIT; there's no partial credit and no negotiation from here, only a full restart with a fresh Discover.

That second case is worth a concrete walkthrough, since it's a different failure than the pool-exhaustion DHCPNAK the DHCP article's own scenario already covered. A laptop suspends for the night while connected to the office network, on the 192.168.1.0/24 segment, holding a lease for 192.168.1.42. Someone picks it up and carries it home, still asleep, and it wakes up connected to a home network on an entirely different subnet, 192.168.50.0/24. Following INIT-REBOOT, the laptop doesn't start with a Discover — it remembers its old lease and broadcasts a Request straight for it:

08:15:02.001 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 08:00:27:4e:66:a1, length 300, xid 0xc4103e91
      Requested-IP Option 50, length 4: 192.168.1.42

The home network's DHCP server, running its own pool for 192.168.50.0/24, sees a Request for an address that has nothing to do with the network the client is actually plugged into and answers with a DHCPNAK rather than trying to honor a request it has no authority to grant:

08:15:02.014 IP 192.168.50.1.67 > 255.255.255.255.68: BOOTP/DHCP, Reply, length 300, xid 0xc4103e91
      DHCP-Message Option 53, length 1: NAK

The laptop, back in INIT, immediately runs full DORA against the home network and ends up with a 192.168.50.x address a moment later — invisible to the user beyond a brief flash of "no internet" while the exchange completes. This is INIT-REBOOT working as intended: fast reconnection when the network hasn't changed, and a quick, clean fallback to full DORA when it has.

Lease renewal itself — what T1 and T2 actually mean, and why renewal mostly happens without anyone noticing — was already covered in the DHCP article; nothing about DHCPACK or DHCPNAK changes that mechanism, they're simply the specific packets that fire when a renewal succeeds or fails.

Self-check

Given a packet capture containing a DHCPNAK, could you tell — from the fields covered across this group of articles, without any accompanying explanation — whether it came from a REQUESTING-state Request or a REBOOTING-state one? What would you look at in the Request that preceded it to decide?

That closes out the lease process itself: a device now has an address, a gateway, and a set of DNS servers to query, entirely without anyone typing a configuration file by hand. Getting an address solved is only half of what makes a private network usable from the outside — the other half is how many devices behind that one address can share it, which is the next problem this module takes on.

Sources