TechnitiumSoftware/DnsServer · warning · DhcpServerException

No lease was found for client identifier: {clientIdentifier}

Error message

No lease was found for client identifier: {clientIdentifier}

What it means

Thrown by Scope.RemoveLease(ClientIdentifierOption) when the concurrent lease dictionary has no entry for the given client identifier (TryRemove returns false). It signals the requested client has no active or reserved lease on this scope.

Source

Thrown at DnsServerCore/Dhcp/Scope.cs:1521

        }

        public Lease RemoveLease(string hardwareAddress)
        {
            byte[] hardwareAddressBytes = Lease.ParseHardwareAddress(hardwareAddress);

            foreach (KeyValuePair<ClientIdentifierOption, Lease> entry in _leases)
            {
                if (entry.Value.HardwareAddress.SequenceEqual(hardwareAddressBytes))
                    return RemoveLease(entry.Key);
            }

            throw new DhcpServerException("No lease was found for hardware address: " + hardwareAddress);
        }

        public Lease RemoveLease(ClientIdentifierOption clientIdentifier)
        {
            if (!_leases.TryRemove(clientIdentifier, out Lease removedLease))
                throw new DhcpServerException("No lease was found for client identifier: " + clientIdentifier.ToString());

            if (removedLease.Type == LeaseType.Reserved)
            {
                //remove reserved lease
                ClientIdentifierOption reservedLeaseClientIdentifier = new ClientIdentifierOption((byte)DhcpMessageHardwareAddressType.Ethernet, removedLease.HardwareAddress);
                if (_reservedLeases.TryGetValue(reservedLeaseClientIdentifier, out Lease existingReservedLease))
                {
                    //remove reserved lease only if the IP addresses match
                    if (existingReservedLease.Address.Equals(removedLease.Address))
                    {
                        if (_reservedLeases.TryRemove(reservedLeaseClientIdentifier, out Lease removedExistingLease))
                        {
                            _dhcpServer.RemoveDnsEntries(this, removedLease, true); //remove DNS entries for allocated lease
                            _dhcpServer.RemoveDnsEntries(this, removedExistingLease, true); //remove DNS entries for reserved lease hostname, if any
                        }
                    }
                }
            }

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Check that a lease for this ClientIdentifierOption exists on the scope before removal.
  2. Ensure the ClientIdentifierOption is constructed with the same hardware-address type and bytes as the stored lease.
  3. If the operation is idempotent in your flow, swallow the DhcpServerException for 'No lease was found'.
  4. Operate on the scope that actually holds the lease.

Example fix

// before
scope.RemoveLease(clientId); // throws if absent

// after
try { scope.RemoveLease(clientId); }
catch (DhcpServerException ex) when (ex.Message.Contains("No lease was found"))
{ _log.Info("lease already absent; skipping"); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!scope.Leases.ContainsKey(clientIdentifier)) return; // no lease to remove

Type guard

static bool ScopeHasLeaseForClient(Scope scope, ClientIdentifierOption id)
    => scope.Leases.ContainsKey(id);

Try / catch

try { scope.RemoveLease(clientIdentifier); }
catch (DhcpServerException ex) when (ex.Message.Contains("No lease was found"))
{ /* idempotent: lease already absent */ }

Prevention

When it happens

Trigger: Calling scope.RemoveLease(clientIdentifier) with a ClientIdentifierOption not present in the leases map: unknown client, expired/already-removed lease, or identifier built with a different hardware-address type than stored.

Common situations: Releasing a lease from stale state, retrying a successful release, mismatched DhcpMessageHardwareAddressType in the ClientIdentifierOption, or targeting the wrong scope.

Related errors


AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13). Data as JSON: /api/errors/b1aefa5e9b541b7a. Report an issue: GitHub.