In a network I was faced with exceptionally large number of IP address DHCP leases for short-time usage. Even though the lease duration was set as relatively short, the DHCP server still occasionally complained about the DHCP scope being full, being unable to assign an IP address to a client.
Let’s demonstrate the situation with a lab setup. Here I have a Windows Server 2022 as the DHCP server, and there is the scope for 192.168.60.0/24 subnet configured with 10 available IP addresses:
I set the lease duration to only 4 minutes (again, this is a lab!). There is no failover configuration in this case, so I don’t have to worry about the MCLT (Maximum Client Lead Time, see my earlier post if you wonder why your leases occasionally come out as one hour instead of the configured lease duration).
Then, let’s request some leases. I’ll use dhtest here, requesting 11 addresses with random MAC addresses, and this is what the DHCP server logged in the log file in C:\Windows\system32\dhcp
:
10,09/27/23,22:35:33,Assign,192.168.60.100,,000102779CEA,,3420294190,0,,,,,,,,,0 10,09/27/23,22:35:35,Assign,192.168.60.101,,0001027415FE,,782297866,0,,,,,,,,,0 10,09/27/23,22:35:38,Assign,192.168.60.102,,000102A4826B,,261183525,0,,,,,,,,,0 10,09/27/23,22:35:39,Assign,192.168.60.103,,000102ECBE08,,796500092,0,,,,,,,,,0 10,09/27/23,22:35:43,Assign,192.168.60.104,,00010235ACB1,,3638647650,0,,,,,,,,,0 10,09/27/23,22:35:45,Assign,192.168.60.105,,000102A0D8A0,,3352944510,0,,,,,,,,,0 10,09/27/23,22:35:47,Assign,192.168.60.106,,00010269A74C,,3111520259,0,,,,,,,,,0 10,09/27/23,22:35:49,Assign,192.168.60.107,,00010204FC4B,,407990128,0,,,,,,,,,0 10,09/27/23,22:35:51,Assign,192.168.60.108,,0001023C9850,,1532426350,0,,,,,,,,,0 10,09/27/23,22:35:52,Assign,192.168.60.109,,000102D06DC5,,2298912365,0,,,,,,,,,0 14,09/27/23,22:35:58,Scope Full,192.168.60.0,,,,0,6,,,,,,,,,0
The first ten clients got their IP address leases nicely, but the 11th client didn’t get anything as the scope was already full.
The leases are shown in the database (I removed the hostname column to compress the output):
PS C:\> (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") 2023-09-27 22.44.18 PS C:\> Get-DhcpServerv4Lease -ScopeId 192.168.60.0 IPAddress ScopeId ClientId AddressState LeaseExpiryTime --------- ------- -------- ------------ --------------- 192.168.60.100 192.168.60.0 00-01-02-77-9c-ea Active 27.9.2023 22.39.33 192.168.60.101 192.168.60.0 00-01-02-74-15-fe Active 27.9.2023 22.39.35 192.168.60.102 192.168.60.0 00-01-02-a4-82-6b Active 27.9.2023 22.39.38 192.168.60.103 192.168.60.0 00-01-02-ec-be-08 Active 27.9.2023 22.39.39 192.168.60.104 192.168.60.0 00-01-02-35-ac-b1 Active 27.9.2023 22.39.43 192.168.60.105 192.168.60.0 00-01-02-a0-d8-a0 Active 27.9.2023 22.39.45 192.168.60.106 192.168.60.0 00-01-02-69-a7-4c Active 27.9.2023 22.39.47 192.168.60.107 192.168.60.0 00-01-02-04-fc-4b Active 27.9.2023 22.39.49 192.168.60.108 192.168.60.0 00-01-02-3c-98-50 Active 27.9.2023 22.39.51 192.168.60.109 192.168.60.0 00-01-02-d0-6d-c5 Active 27.9.2023 22.39.52
Looks fine, all leases are Active.
Except that the current time is already 22:44:18, shouldn’t the leases be all expired by now?
So, what’s going on? Why are the leases still shown as Active even though they all have already expired?
The “secret” component in Windows DHCP service is Database Cleanup. It happens every 60 minutes by default, and it is its job to get the expired leases out of the way.
Incidentally, a moment later this was shown in the log:
24,09/27/23,22:47:38,Database Cleanup Begin,,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.100,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.101,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.102,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.103,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.104,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.105,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.106,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.107,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.108,,,,0,6,,,,,,,,,0 18,09/27/23,22:47:38,Expired,192.168.60.109,,,,0,6,,,,,,,,,0
And now all the leases seem to be available:
PS C:\> Get-DhcpServerv4Lease -ScopeId 192.168.60.0 PS C:\>
But, when I test the with a DHCP client, it still doesn’t get a lease, and the DHCP server logs that the scope is still full:
14,09/27/23,22:48:42,Scope Full,192.168.60.0,,,,0,6,,,,,,,,,0
What this all means is that the leases switched to Expired
state, but they were still allocated to the clients. These expired leases can be seen with the -AllLeases
parameter:
PS C:\> Get-DhcpServerv4Lease -ScopeId 192.168.60.0 -AllLeases IPAddress ScopeId ClientId AddressState LeaseExpiryTime --------- ------- -------- ------------ --------------- 192.168.60.100 192.168.60.0 00-01-02-77-9c-ea Expired 27.9.2023 22.39.33 192.168.60.101 192.168.60.0 00-01-02-74-15-fe Expired 27.9.2023 22.39.35 192.168.60.102 192.168.60.0 00-01-02-a4-82-6b Expired 27.9.2023 22.39.38 192.168.60.103 192.168.60.0 00-01-02-ec-be-08 Expired 27.9.2023 22.39.39 192.168.60.104 192.168.60.0 00-01-02-35-ac-b1 Expired 27.9.2023 22.39.43 192.168.60.105 192.168.60.0 00-01-02-a0-d8-a0 Expired 27.9.2023 22.39.45 192.168.60.106 192.168.60.0 00-01-02-69-a7-4c Expired 27.9.2023 22.39.47 192.168.60.107 192.168.60.0 00-01-02-04-fc-4b Expired 27.9.2023 22.39.49 192.168.60.108 192.168.60.0 00-01-02-3c-98-50 Expired 27.9.2023 22.39.51 192.168.60.109 192.168.60.0 00-01-02-d0-6d-c5 Expired 27.9.2023 22.39.52
As far as I know, there is no way to see the Expired
leases in the DHCP MMC (the management console), so you have to use PowerShell to see them.
So, while the leases have been expired due to the short lease duration, the leases are still kept reserved for those clients, if they happen to come back to network to request them again.
Based on this old document about the DHCP service in Windows Server 2003 (the best Microsoft-published documentation I could find on this), the grace period for expired leases is 4 hours.
Basically, after the database cleanup has expired the leases, it will still take 4 hours before the cleanup run will actually delete the expired leases.
However, there is some adaptive algorithm in the background as well. In some situations the expired leases can be deleted already earlier, apparently in situations where the scope is full and new clients have been asking for addresses. In those cases the database cleanup can actually run out-of-schedule as needed.
There are two ways to influence the described behavior if needed:
- You can adjust the scheduled database cleanup interval (default = 60 minutes) with a registry setting:
DatabaseCleanupInterval
inComputer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DHCPServer\Parameters
(the value is specified in minutes) - You can adjust the expired lease grace period (default = 4 hours) with another registry setting:
LeaseExtension
inComputer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DHCPServer\Parameters
(this value does not exist by default; create it as DWORD value, and set the value in seconds)
Note that if the DHCP client releases the lease with a DHCPRELEASE message, the lease is deleted right away, so the discussion above basically concerns only leases that have not been released, but not renewed either.
Conclusions
These are the conclusions when using the Windows Server DHCP service (other DHCP server implementations may have similar features):
- The configured lease duration is not the only parameter that affects the IP address availability after client has stopped renewing the lease.
- Active leases are expired and eventually deleted only when the database cleanup runs (see the DHCP log files for the activity).
- The database cleanup can also run sooner than configured if the DHCP service decides so (based on the DHCP client activity, scope utilization, or some other factor).
- The default grace period after lease expiration is 4 hours but it can also be shorter if the DHCP service decides so.
- Use
Get-DhcpServerv4Lease -AllLeases
to see the actual current utilization of a DHCP scope.