{"record":{"id":"db34a55f930d949d","repo":"TechnitiumSoftware/DnsServer","slug":"no-reserved-lease-was-found-for-hardware-address","errorCode":null,"errorMessage":"No reserved lease was found for hardware address: {hardwareAddress}","messagePattern":"No reserved lease was found for hardware address: (.+?)","errorType":"exception","errorClass":"DhcpServerException","httpStatus":null,"severity":"warning","filePath":"DnsServerCore/Dhcp/Scope.cs","lineNumber":1590,"sourceCode":"            ConvertToReservedLease(lease);\n        }\n\n        public void ConvertToDynamicLease(string hardwareAddress)\n        {\n            byte[] hardwareAddressBytes = Lease.ParseHardwareAddress(hardwareAddress);\n\n            foreach (KeyValuePair<ClientIdentifierOption, Lease> entry in _leases)\n            {\n                Lease lease = entry.Value;\n\n                if ((lease.Type == LeaseType.Reserved) && lease.HardwareAddress.SequenceEqual(hardwareAddressBytes))\n                {\n                    ConvertToDynamicLease(lease);\n                    return;\n                }\n            }\n\n            throw new DhcpServerException(\"No reserved lease was found for hardware address: \" + hardwareAddress);\n        }\n\n        public void ConvertToDynamicLease(ClientIdentifierOption clientIdentifier)\n        {\n            if (!_leases.TryGetValue(clientIdentifier, out Lease lease) || (lease.Type != LeaseType.Reserved))\n                throw new DhcpServerException(\"No reserved lease was found for client identifier: \" + clientIdentifier.ToString());\n\n            ConvertToDynamicLease(lease);\n        }\n\n        public void WriteTo(Stream s)\n        {\n            BinaryWriter bW = new BinaryWriter(s);\n\n            bW.Write(Encoding.ASCII.GetBytes(\"SC\"));\n            bW.Write((byte)10); //version\n\n            s.WriteShortString(_name);","sourceCodeStart":1572,"sourceCodeEnd":1608,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dhcp/Scope.cs#L1572-L1608","documentation":"Thrown by Scope.ConvertToDynamicLease(string hardwareAddress) when no RESERVED lease matches the hardware address. Only a Reserved lease can be demoted to Dynamic; an absent or already-dynamic lease triggers this error.","triggerScenarios":"Calling scope.ConvertToDynamicLease(mac) where the matching lease is Dynamic, Static, or missing. The loop only converts when lease.Type == LeaseType.Reserved and the MAC matches.","commonSituations":"Demoting a client that has no reservation, re-demoting an already-dynamic lease, or MAC format mismatch with stored HardwareAddress.","solutions":["Confirm a Reserved lease exists for the MAC on this scope before demoting.","If the lease is already Dynamic, no conversion is needed.","Remove and re-add as dynamic if state is inconsistent.","Verify the MAC string format against the stored value."],"exampleFix":"// before\nscope.ConvertToDynamicLease(mac); // throws if not reserved\n\n// after\nvar lease = scope.Leases.FirstOrDefault(l => l.Type == LeaseType.Reserved && l.HardwareAddress.SequenceEqual(Lease.ParseHardwareAddress(mac)));\nif (lease != null) scope.ConvertToDynamicLease(mac);","handlingStrategy":"validation","validationCode":"byte[] mac = Lease.ParseHardwareAddress(macString);\nbool convertible = scope.Leases.Any(l => l.Type == LeaseType.Reserved && l.HardwareAddress.SequenceEqual(mac));\nif (!convertible) return;","typeGuard":"static bool HasReservedLeaseForHardware(Scope scope, string mac){\n    var bytes = Lease.ParseHardwareAddress(mac);\n    return scope.Leases.Any(l => l.Type == LeaseType.Reserved && l.HardwareAddress.SequenceEqual(bytes));\n}","tryCatchPattern":"try { scope.ConvertToDynamicLease(macString); }\ncatch (DhcpServerException ex) when (ex.Message.Contains(\"No reserved lease\"))\n{ /* nothing reserved to demote */ }","preventionTips":["Only demote leases you know are Reserved.","Refresh state before exposing demote actions.","Normalize MAC format before lookup."],"tags":["dhcp","lease","runtime-state","scope","reservation"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}