I'm feeling like an idiot right now. I tried STFW and the forum and not finding an obvious answer. I swear I read something recently that this was a (recently new?) feature but I'm struggling.
Is it seriously not possible to delete a DHCP lease under DNSmasq? I am looking at Services > Dnsmasq DNS & DHCP > Leases and staring at a table of leases, but there's no UI indication on a way to delete/forget a lease.
I tried rebooting the OPNsense firewall as a hail mary but unsurprisingly that didn't do anything.
It did not make the cut:
https://github.com/opnsense/core/pull/8899
Thanks for sharing. If I'm reading that right, the "issue" that caused me to ask the question (reservation not seeming to take effect) is likely an issue with the client system in question not doing a release.
Yeah the client system either needs a reboot or a DHCP RELEASE, but it would need one anyway even if you delete a lease from dnsmasq.
There is no mechanism to tell the client "hey get rid of your current dhcp lease and take a new one".
Only the client can do this via a DHCP RELEASE, or when it asks via a new DHCP DISCOVER after e.g. restarting the network interface or a reboot.
Dnsmasq will then offer the new IP address that was reserved during the next DHCP DISCOVER cycle.
What's funny is I did reboot the client system and that didn't influence the behavior either. Idk. Don't want to overthink it.
I just had the case where dnsmasq handed out the IPv4 or a lease instead of the static configured one requiring to delete the lease in /var/db/dnsmasq.leases manually.
Please reconsider this pull request!
Idk. I'm on the fence on whether this "issue" merits a dev response or not.
It certainly would be a nice to have and similar router/firewall software offer lease deletion.
However, this is a "two to tango" and in my case, my client (TrueNAS, but I fail to recall what version it was at the time) eventually did pick up the new lease after the existing lease expired (IIRC my setting is a 24-hour lease). A simple administrator workaround is to appropriately configure their lease times.
I agree with a previous commentor where they said (paraphrasing) that if the DHCP client isn't RFC compliant and isn't assuming it should grab a totally new lease on reboot, it's the fault of the client and not OPNsense. To this part, I am in full agreement. I certainly can't quote the RFC off the top of my head, but I recall reading language within it that DHCP clients should not assume they're on the same network segment as before a major system event such as a reboot. I think there's something in there about a NIC connection change too, but again - none of this is direct quote, simply sensible.
My use case is onboarding a new device on the network not knowing its MAC address.
When the dynamic lease is created I create a static with some fixed IPv4/6 addresses for it and want it to be picked up immediately when I reconnect the device to my network.
This is from my dnsmasq logs where the dynamic assigned 10.0.0.92 from the initial dhcp discover was assigned by dnsmasq although I already had created a static entry for 10.0.0.231
2025-08-08T16:43:47 Informational dnsmasq-dhcp DHCPACK(re1_vlan1) 10.0.0.92 8c:30:66:7e:29:5c
2025-08-08T16:43:47 Informational dnsmasq-dhcp DHCPREQUEST(re1_vlan1) 10.0.0.92 8c:30:66:7e:29:5c
2025-08-08T16:43:43 Informational dnsmasq-dhcp DHCPOFFER(re1_vlan1) 10.0.0.92 8c:30:66:7e:29:5c
2025-08-08T16:43:43 Informational dnsmasq-dhcp DHCPDISCOVER(re1_vlan1) 8c:30:66:7e:29:5c
But it does without deleting a lease, just dont forget to hit apply.
https://github.com/opnsense/core/pull/8899#issuecomment-3033118948
It didn't work as my logs prove...
Yeah....I just did a similar set of work today, not exactly the same....but dnsmasq doesn't appear to be respecting the host configuration. I absolutely hit the apply button and I even restarted dnsmasq for good measure, but the packet capture is clear as day. When the DHCP client rebooted, it did a DHCP discover requesting the temporary/dynamic/lease-pool address it had previously, offered it, and acknowledged it.
EDIT:
Ive read the RFC norm and there is an INIT-REBOOT behavior where the client will actually try to get the last IP it remembered before the reboot.
It looks like only a clean DHCP RELEASE will break this behavior.
Or DNSMASQ should send a DHCP-NAK to refuse giving out the IP the client requests.
RFC2131:
DHCPREQUEST generated during INIT-REBOOT state:
'server identifier' MUST NOT be filled in, 'requested IP address'
option MUST be filled in with client's notion of its previously
assigned address. 'ciaddr' MUST be zero. The client is seeking to
verify a previously allocated, cached configuration. Server SHOULD
send a DHCPNAK message to the client if the 'requested IP address'
is incorrect, or is on the wrong network.
The source code of dnsmasq shows specific behavior for this scenario:
https://github.com/imp/dnsmasq/blob/770bce967cfc9967273d0acfb3ea018fb7b17522/src/rfc2131.c#L1305
If client requests old IP but a matching dhcp-host exists with a different IP and that IP isn't currently leased → set reason "static lease available" → NAK.
If the requested IP is reserved for some other host → set reason "address reserved" → NAK.
Otherwise, ACK if valid/available.
Maybe checking the option DHCP Authoritative in the general dnsmasq options make a difference.
The code path seems to reference it as well.
Setting the checkbox for "DHCP authoritative", applying, restarting dnsmasq, and then restarting the client had no effect. Client still requests and is given the leased IP.
Then you must have taken one of the code paths stated above:
- The reservation IP address was already dynamically leased to another host. In that case the original host will receive the old IP as fallback, until that lease expires. Otherwise there would be duplicate IP addresses.
Can you check for that?
(Please keep in mind, deleting a lease from the database does not tell any client in the network to drop their current lease)
Quote from: Monviech (Cedrik) on August 17, 2025, 08:10:07 AM- The reservation IP address was already dynamically leased to another host. In that case the original host will receive the old IP as fallback, until that lease expires. Otherwise there would be duplicate IP addresses.
Can you check for that?
Definitely not. My process was approximately as follows:
1. Shutdown original system (which has the host definition/DHCP reservation outside the dynamic pool/range).
2. Reduce DHCP lease time from 8 hours to 1 hour (3600 seconds).
3. Install fresh installation of TrueNAS Scale (TN) on new motherboard with new NIC. It gets a lease from pool/range.
4. Restore configuration of TN. (Configuration restore creates a bridge interface, but doesn't maintain the same MAC as before step 1).
5. Figure out the MAC of the bridge interface, update host definition. Apply. Restart Dnsmasq.
6. Wait over an hour, no change. Reboot the TN. No change.
7. Make your recommended DHCP authoritative change, restart dnsmasq. Reboot the TN. No change.
8. Wait over an hour, no change.
9. Give up, set the TN box to the desired "permanent" reserved/static IP address. Wait an hour. Check that the old lease is gone, switch TN box back to DHCP. Works.
I didn't notice/check them at the time of all these issues, but the webui's Services > DNsmasq DNS & DHCP > Log File page has the following two warning events repeating over and over. Pretend 192.0.2.100 is a dynamic address, and 192.0.2.10 is the reservation.
not giving name HOSTNAME to the DHCP lease of 192.0.2.100 because the name exists in /var/etc/dnsmasq-hosts with address 192.0.2.10
not giving name HOSTNAME.SUBDOMAIN.DOMAIN.TLD to the DHCP lease of 192.0.2.100 because the name exists in /var/etc/dnsmasq-hosts with address 192.0.2.10
For me it works exactly as described above, and as outlined in the Dnsmasq source code.
Workflow:
- Windows Client gets dynamic IP: 172.16.0.132
- Give it a reservation: 172.16.0.108, press Apply
- Reboot Windows Client
- In tcpdump you can see that client requests 172.16.0.132, but gets a DHCP NAK and then does a full DHCP Discover
- Windows Client gets static IP: 172.16.0.108 after reboot.
---- Before reboot ---
- Here the client asks and receives its current IP address (172.16.0.132) /before/ getting a reservation
No. Time Source Destination Protocol Length Info
1 0.000000 0.0.0.0 255.255.255.255 DHCP 354 DHCP Request - Transaction ID 0x65f20d29
2 0.022221 172.16.0.1 172.16.0.132 DHCP 376 DHCP ACK - Transaction ID 0x65f20d29
---- After reboot ---
- Here the client asks for its old IP address (172.16.0.132), but is actively denied by Dnsmasq (DHCP NAK)
3 184.282607 0.0.0.0 255.255.255.255 DHCP 354 DHCP Request - Transaction ID 0x1e64e5aa
Frame 3: 354 bytes on wire (2832 bits), 354 bytes captured (2832 bits)
Ethernet II, Src: Microsoft_c1:24:4c (f0:6e:0b:c1:24:4c), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 0.0.0.0, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 68, Dst Port: 67
Dynamic Host Configuration Protocol (Request)
Message type: Boot Request (1)
Hardware type: Ethernet (0x01)
Hardware address length: 6
Hops: 0
Transaction ID: 0x1e64e5aa
Seconds elapsed: 0
Bootp flags: 0x0000 (Unicast)
Client IP address: 0.0.0.0
Your (client) IP address: 0.0.0.0
Next server IP address: 0.0.0.0
Relay agent IP address: 0.0.0.0
Client MAC address: Microsoft_c1:24:4c (f0:6e:0b:c1:24:4c)
Client hardware address padding: 00000000000000000000
Server host name not given
Boot file name not given
Magic cookie: DHCP
Option: (53) DHCP Message Type (Request)
Length: 1
DHCP: Request (3)
Option: (61) Client identifier
Option: (50) Requested IP Address (172.16.0.132)
Length: 4
Requested IP Address: 172.16.0.132
Option: (12) Host Name
Option: (81) Client Fully Qualified Domain Name
Option: (60) Vendor class identifier
Option: (55) Parameter Request List
Option: (255) End
4 184.304084 172.16.0.1 255.255.255.255 DHCP 342 DHCP NAK - Transaction ID 0x1e64e5aa
Frame 4: 342 bytes on wire (2736 bits), 342 bytes captured (2736 bits)
Ethernet II, Src: Deciso_00:d9:f4 (f4:90:ea:00:d9:f4), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 172.16.0.1, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 67, Dst Port: 68
Dynamic Host Configuration Protocol (NAK)
Message type: Boot Reply (2)
Hardware type: Ethernet (0x01)
Hardware address length: 6
Hops: 0
Transaction ID: 0x1e64e5aa
Seconds elapsed: 0
Bootp flags: 0x8000, Broadcast flag (Broadcast)
Client IP address: 0.0.0.0
Your (client) IP address: 0.0.0.0
Next server IP address: 0.0.0.0
Relay agent IP address: 0.0.0.0
Client MAC address: Microsoft_c1:24:4c (f0:6e:0b:c1:24:4c)
Client hardware address padding: 00000000000000000000
Server host name not given
Boot file name not given
Magic cookie: DHCP
Option: (53) DHCP Message Type (NAK)
Length: 1
DHCP: NAK (6)
Option: (54) DHCP Server Identifier (172.16.0.1)
Option: (56) Message
Option: (255) End
Padding: 0000000000000000000000000000000000000000000000000000
- Now a full DHCP Discover starts, and the Reservation IP (172.16.0.108) is offered and ACK.
5 184.385874 0.0.0.0 255.255.255.255 DHCP 342 DHCP Discover - Transaction ID 0xb123c37e
6 184.406124 172.16.0.1 172.16.0.108 DHCP 348 DHCP Offer - Transaction ID 0xb123c37e
7 184.414919 0.0.0.0 255.255.255.255 DHCP 360 DHCP Request - Transaction ID 0xb123c37e
8 184.448230 172.16.0.1 172.16.0.108 DHCP 376 DHCP ACK - Transaction ID 0xb123c37e
There must be some sort of difference in our configuration, how we do things, or how different clients handle this. Essentially it should be explainable in some way.
>Give it a reservation: 172.16.0.108, press Apply
Maybe there's a misunderstanding. What I am reporting and what the others (I think) are trying to report is the below "problem", not what you describe:
1. A DHCP reservation/host definition exists for an IP/MAC binding.
2. A (planned or unplanned) failure occurs to the original device with that MAC.
3. A new device with a new MAC to replace the original device/MAC is added to the network and gets a DHCP lease.
4. After the reservation/host definition is updated with the new MAC, Dnsmasq is not NACK'ing DHCP discovers/requests and is continuing with the temporary lease in spite of the reservation/host definition.
I understand but I guess that makes sense.
Dnsmasq does not know if the old client MAC ever comes back as long as the lease time is still valid.
It will fall in the code path:
- The current (changed MAC address) reservation overlaps with an existing (old MAC address) lease, thus it will not be offered, a dynamic lease is offered instead.
Few different comments I guess.
* So I could be mistaken, but I don't *remember* seeing the original reservation's lease on the Leases page after the reservation was edited to the new MAC address (the right-hand graphic had the magnifying glass to go straight to the host configuration, versus the + sign to add a new one).
* I think this discussion proves there *is* merit to having a function to delete a lease. Whether or not Dnsmasq can do this is a separate question.
* Perhaps this is the wrong forum for this discussion and it needs to be had 'upstream'.
* I didn't think to try it before an earlier comment of yours (Cedrik) but maybe an appropriate workaround would have been to completely delete the reservation/host definition and re-create it. It may not be quite so simple, however.
I guess if there is merit or not also depends on network design.
Some might consider giving servers static IP addresses manually, and letting DHCP handle clients.
The IP address itself might also not be as valuable if most of the network uses dynamic FQDNs which Dnsmasq can register.
If you think there is a usecase we did not consider, open an issue on our github page.
The viability to add this to dnsmasq has been tried out, and its complicated. A delete button is very niche and it looks like only needed for a very specific edge case. Offering it broadly suggests its a requirement, when it is not in most cases.
https://github.com/opnsense/core/pull/8899