TechnitiumSoftware/DnsServer · warning · DhcpServerException
No dynamic lease was found for hardware address: {hardwareAd
Error message
No dynamic lease was found for hardware address: {hardwareAddress} What it means
Thrown by Scope.ConvertToReservedLease(string hardwareAddress) when no DYNAMIC lease matches the hardware address. Only a currently-dynamic lease can be promoted to reserved; reserved or absent leases cause this error.
Source
Thrown at DnsServerCore/Dhcp/Scope.cs:1564
return removedLease;
}
public void ConvertToReservedLease(string hardwareAddress)
{
byte[] hardwareAddressBytes = Lease.ParseHardwareAddress(hardwareAddress);
foreach (KeyValuePair<ClientIdentifierOption, Lease> entry in _leases)
{
Lease lease = entry.Value;
if ((lease.Type == LeaseType.Dynamic) && lease.HardwareAddress.SequenceEqual(hardwareAddressBytes))
{
ConvertToReservedLease(lease);
return;
}
}
throw new DhcpServerException("No dynamic lease was found for hardware address: " + hardwareAddress);
}
public void ConvertToReservedLease(ClientIdentifierOption clientIdentifier)
{
if (!_leases.TryGetValue(clientIdentifier, out Lease lease) || (lease.Type != LeaseType.Dynamic))
throw new DhcpServerException("No dynamic lease was found for client identifier: " + clientIdentifier.ToString());
ConvertToReservedLease(lease);
}
public void ConvertToDynamicLease(string hardwareAddress)
{
byte[] hardwareAddressBytes = Lease.ParseHardwareAddress(hardwareAddress);
foreach (KeyValuePair<ClientIdentifierOption, Lease> entry in _leases)
{
Lease lease = entry.Value;
View on GitHub (pinned to d0484b6c1e)
Solutions
- Confirm a dynamic lease exists for the MAC on this scope before promoting.
- If the lease is already Reserved, no conversion is needed.
- Register a reservation directly instead of converting if no dynamic lease exists.
- Verify MAC format matches the stored HardwareAddress.
Example fix
// before scope.ConvertToReservedLease(mac); // throws if not dynamic // after var lease = scope.Leases.FirstOrDefault(l => l.Type == LeaseType.Dynamic && l.HardwareAddress.SequenceEqual(Lease.ParseHardwareAddress(mac))); if (lease != null) scope.ConvertToReservedLease(mac); else scope.AddReservedLease(...); // create reservation directly
Defensive patterns
Strategy: validation
Validate before calling
byte[] mac = Lease.ParseHardwareAddress(macString);
bool convertible = scope.Leases.Any(l => l.Type == LeaseType.Dynamic && l.HardwareAddress.SequenceEqual(mac));
if (!convertible) { /* add reservation directly instead */ } Type guard
static bool HasDynamicLeaseForHardware(Scope scope, string mac){
var bytes = Lease.ParseHardwareAddress(mac);
return scope.Leases.Any(l => l.Type == LeaseType.Dynamic && l.HardwareAddress.SequenceEqual(bytes));
} Try / catch
try { scope.ConvertToReservedLease(macString); }
catch (DhcpServerException ex) when (ex.Message.Contains("No dynamic lease"))
{ /* fall back to creating a reservation explicitly */ } Prevention
- Only convert leases you know are currently Dynamic.
- If unsure of lease type, add a reservation directly.
- Refresh lease state before exposing convert actions in a UI.
When it happens
Trigger: Calling scope.ConvertToReservedLease(mac) where the matching lease is Reserved (already reserved), Static, or does not exist at all. The loop only converts when lease.Type == LeaseType.Dynamic and the MAC matches.
Common situations: Promoting a client that was never given a dynamic lease, re-promoting an already-reserved lease, or passing a MAC whose stored lease is not Dynamic.
Related errors
- No dynamic lease was found for client identifier: {clientIde
- No reserved lease was found for hardware address: {hardwareA
- No reserved lease was found for client identifier: {clientId
- No lease was found for hardware address: {hardwareAddress}
- No lease was found for client identifier: {clientIdentifier}
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/a89374c2f94f19c6.
Report an issue: GitHub.