Windows DHCP Bad_Address

Open the Windows DHCP console and find dozens or hundreds of addresses showing as BAD_ADDRESS, and the obvious reaction is to clear them.

That’s usually the wrong move.

A BAD_ADDRESS entry means something determined that the address shouldn’t be handed to a client. Deleting the entry removes the record, not the reason.

The useful question isn’t:

“How do I clear the BAD_ADDRESS entries?”

It’s:

“What detected a conflict, and why?”

There are two separate mechanisms that produce these entries, and knowing which one you’re dealing with changes where you look.

Client-side duplicate address detection. A DHCP client receives an address, discovers something else already using it, and sends a DHCPDECLINE. The server records the address as bad.

Server-side conflict detection. Windows DHCP checks an address before leasing it. This is controlled by ConflictDetectionAttempts, and it is disabled by default.

That second point explains most of the confusion around this problem.

What BAD_ADDRESS actually means

In the DHCP console, a bad address is one DHCP considers unavailable because of a detected conflict. PowerShell calls these bad or declined leases, and the AddressState is normally Declined.

Find them across the whole server:

powershell

Get-DhcpServerv4Lease -BadLeases

Or for one scope:

powershell

Get-DhcpServerv4Lease -ScopeId 192.168.10.0 -BadLeases

Microsoft’s Get-DhcpServerv4Lease documentation confirms that specifying -BadLeases without -ScopeId returns bad leases from the entire server.

One detail worth knowing

You’ll often read that a bad address is blocked permanently until you clear it manually.

Microsoft’s documentation says otherwise: an address lease in the declined state is not offered to any client until a ten-minute timer expires.

In practice, administrators routinely see BAD_ADDRESS entries persisting far longer than ten minutes, which suggests either the conflict keeps recurring or the console is showing historical records rather than active blocks.

Either way, it’s worth knowing the documented behaviour before assuming a stale entry is blocking an address you need.

DHCPDECLINE versus server-side conflict detection

Client-side duplicate address detection

The sequence looks like this:

text

DHCP server
    |
    | DHCP OFFER
    v
Client receives 192.168.10.50
    |
    | Gratuitous ARP
    v
Client finds 192.168.10.50 already in use
    |
    | DHCPDECLINE
    v
DHCP server
    |
    v
Address recorded as Declined / BAD_ADDRESS

Windows clients perform duplicate address detection before finishing configuration of a DHCP-supplied address. If the gratuitous ARP gets a response, the client declines.

The DHCP server never has to detect the conflict itself. The client does.

Server-side conflict detection

Windows DHCP has its own check, and it’s off by default.

powershell

Get-DhcpServerSetting | Select-Object ConflictDetectionAttempts

The default is 0. Supported values are 0 through 5.

To enable a single attempt:

powershell

Set-DhcpServerSetting -ConflictDetectionAttempts 1

Each attempt is a ping sent before the address is offered. More attempts means more checking, but also more delay in address allocation and more traffic during DHCP operations. One or two is plenty; higher values mostly add latency.

Treat conflict detection as a safety net, not a fix. If a static device is sitting inside your DHCP pool, enabling conflict detection doesn’t solve that. It just makes DHCP more likely to notice before handing the address to someone else.

Why this matters with hundreds of bad entries

Say ConflictDetectionAttempts is 0 on your server, and you have 200 BAD_ADDRESS entries.

“The server isn’t checking addresses, so where did these come from?”

The clients.

Each one received an address, found it in use, and declined it. The server recorded every decline. Server-side conflict detection was never involved.

That’s the single most useful thing to understand here, and it immediately redirects the investigation away from the DHCP server and towards whatever is answering on those addresses.

What makes a client decline an address?

Something else is using it. The interesting part is what that something is.

A static IP inside the DHCP scope

Still the most common cause.

Say your subnet is planned like this:

PurposeRange
Network infrastructure192.168.10.1 – 192.168.10.20
Servers and static devices192.168.10.21 – 192.168.10.49
DHCP clients192.168.10.50 – 192.168.10.220
Reserved for growth192.168.10.221 – 192.168.10.254

Someone configures a printer with 192.168.10.75, inside the DHCP pool.

DHCP has no idea. It eventually offers .75 to a client. The client’s duplicate address detection gets a reply from the printer. The client declines. The server records a bad address.

You clear it. A few days later it comes back.

That’s why deleting entries doesn’t work. The printer is still there.

A device moved into the DHCP range

The device doesn’t have to have been misconfigured originally.

Someone changed a subnet, replaced a switch, moved a device between VLANs, restored from backup, or resized the DHCP scope. An address that was safely outside the pool is now inside it.

Worth comparing the current DHCP scope against your static addressing plan, rather than only looking at the DHCP server.

Reservations confused with static addresses

They’re not the same thing.

A reservation tells the DHCP server: give this client this address.

A static configuration tells the device: use this address regardless of what DHCP says.

Reservations keep the DHCP server as the source of truth, which means the address can’t be handed to anyone else. For devices that need a predictable address but can use DHCP, a reservation is nearly always the better choice.

A cloned or restored system

Badly cloned VMs can end up with duplicate MAC addresses, duplicated machine configurations, or copied virtual network adapters. Restored snapshots can reintroduce an address the network has since reallocated.

Worth checking, but don’t jump to it. First establish whether the address is genuinely being claimed by more than one device.

Network infrastructure causing a false positive

This one is easy to miss, because the device that triggers the decline isn’t using the address at all.

Layer 3 switches and routers with IP Device Tracking send ARP probes. If one arrives while a Windows client is performing duplicate address detection, the client can conclude the address is in use and decline it.

Microsoft has documented this specific interaction.

The lesson: a DHCPDECLINE doesn’t prove another endpoint has the address configured. It proves something replied. Those aren’t the same thing, and chasing a phantom device because of a switch feature wastes a lot of time.

Rogue DHCP servers are a different problem

Worth separating, because they get conflated.

A rogue DHCP server causes clients to receive unexpected addresses, subnet masks, gateways or DNS servers. That’s a different symptom from BAD_ADDRESS entries.

On a client:

cmd

ipconfig /all

The DHCP Server line tells you which server supplied the configuration. If it isn’t yours, you have a rogue.

To list servers authorised in Active Directory:

powershell

Get-DhcpServerInDC

That tells you what’s authorised. It does not discover unauthorised servers – an unauthorised server by definition isn’t in that list.

For finding one, a packet capture showing multiple DHCP Offers will identify the source, and DHCP snooping on managed switches prevents the problem rather than detecting it after the fact.

Finding the device causing the conflict

This is where the work actually pays off.

Start with the bad leases:

powershell

Get-DhcpServerv4Lease -BadLeases |
    Select-Object IPAddress, ClientId, HostName, AddressState

Pick an address and test it:

cmd

ping 192.168.10.75

If something answers, get its MAC:

cmd

arp -a 192.168.10.75

text

Interface: 192.168.10.20
  Internet Address      Physical Address      Type
  192.168.10.75         00-11-22-33-44-55     dynamic

Now you have something to work with.

Identify the vendor

Look up the first three octets against an OUI database. That won’t tell you which physical device it is, but it turns “something is using this address” into “this looks like a printer” or “this is a virtualisation vendor”, which narrows the search considerably.

Find the switch port

If the device is on a managed switch, search the MAC address table. On Cisco IOS:

text

show mac address-table address 0011.2233.4455

That gives you the port. From there, work through the topology until you find the device.

Ten minutes of this beats months of clearing leases.

If the address doesn’t respond to ping

A silent address doesn’t prove it’s unused.

  • Windows Firewall blocks ICMP by default on many profiles
  • Network appliances often don’t respond to ping
  • The device may be off right now
  • The address may be used intermittently
  • The conflict may have resolved before you looked

Check ARP anyway, or generate traffic to the address first and then inspect the cache. For a stubborn case, a packet capture is more informative than repeated pings from one workstation.

Check the DHCP audit logs

Windows DHCP writes audit logs to:

text

%windir%\System32\dhcp

Files are named by day:

text

DhcpSrvLog-Mon.log
DhcpSrvLog-Tue.log

Conflict entries appear with event ID 13:

text

13,11/22/19,09:30:43,Conflict,10.2.29.108,BAD_ADDRESS,,,0,6,,,,,,,,,0

These are DHCP audit log IDs, not Windows Event Viewer event IDs. The two number ranges are unrelated and mixing them up sends people looking in the wrong place.

The logs are useful for establishing when the conflicts happened. A burst of entries on one afternoon points at a change that day. A steady trickle over weeks points at a device that’s been there all along.

Clearing bad leases

Once you’ve investigated, remove them.

All bad leases on the server:

powershell

Remove-DhcpServerv4Lease -BadLeases

One scope:

powershell

Remove-DhcpServerv4Lease -ScopeId 192.168.10.0 -BadLeases

Microsoft’s Remove-DhcpServerv4Lease documentation confirms that -BadLeases without -ScopeId removes bad leases from every scope on the server.

If you prefer to pipe, note that -BadLeases belongs on the Get, not the Remove:

powershell

Get-DhcpServerv4Lease -BadLeases | Remove-DhcpServerv4Lease

The objects coming down the pipeline are already the bad leases. Adding -BadLeases to the Remove cmdlet as well changes which parameter set it uses and isn’t what you want.

Use -WhatIf first if you’re unsure:

powershell

Get-DhcpServerv4Lease -BadLeases | Remove-DhcpServerv4Lease -WhatIf

Don’t clear first

If you have 200 bad addresses and delete all 200 immediately, you’ve destroyed the evidence.

Better order:

  1. Identify several affected addresses
  2. Check when they appeared
  3. Determine whether they’re actually in use
  4. Identify the device or condition causing it
  5. Fix that
  6. Then clear the leases
  7. Watch whether new ones appear

Step 7 is how you know whether you actually fixed it.

A troubleshooting workflow

Count them

powershell

Get-DhcpServerv4Lease -BadLeases |
    Group-Object ScopeId |
    Select-Object Name, Count

One scope or several? That’s the first fork in the road.

List them

powershell

Get-DhcpServerv4Lease -BadLeases |
    Select-Object ScopeId, IPAddress, ClientId, HostName

Look for patterns. Clustered addresses suggest a range someone has statically assigned. Scattered addresses suggest something else.

Check the server setting

powershell

Get-DhcpServerSetting | Select-Object ConflictDetectionAttempts

If it’s 0, the server didn’t create these. The clients did, and you should be looking at what’s on the wire rather than at DHCP configuration.

Investigate one address

Ping it, check ARP, get the MAC, trace the port.

Check the audit logs

Establish when the conflicts occurred and whether they’re ongoing or historical.

Check for static addressing

Compare the affected addresses against printers, cameras, firewalls, switches, access points, servers, hypervisors, appliances and lab equipment.

Most organisations have a spreadsheet somewhere that’s out of date. That’s usually where the answer is.

Check the infrastructure

If the address appears genuinely unused, look at IP Device Tracking, ARP inspection, DHCP snooping, Layer 3 switches, firewalls and segmentation.

Fix the cause, then clear

And watch for new entries.

Designing the scope to avoid this

Most of this problem disappears with a clean addressing plan.

The exact ranges don’t matter. The separation does.

Static addresses should never overlap the DHCP pool. For devices that need a predictable address but support DHCP, use a reservation rather than configuring the address on the device.

That keeps the DHCP server as the authority on what’s allocated, gives you central visibility, and makes it far easier to change the plan later.

BAD_ADDRESS is information, not a fault

A scope full of bad addresses doesn’t mean DHCP is broken. It usually means DHCP is telling you something about the network.

The questions worth asking:

  • Why was the address considered in use?
  • Did a client send DHCPDECLINE, or did the server detect it?
  • Is server-side conflict detection even enabled?
  • Is there a static device inside the pool?
  • Is network infrastructure generating ARP probes?
  • Is a cloned or restored device involved?
  • Is it confined to one VLAN?
  • Did it start after a change?

The distinction that matters most: the DHCP server doesn’t have to be the thing detecting the conflict. With server-side conflict detection disabled by default, the clients are usually doing the detecting, and the server is just recording what they told it.

Once that’s clear, BAD_ADDRESS stops being a list of red entries to clean up and becomes a reasonably precise pointer to something on the network that isn’t where the addressing plan says it should be.

Microsoft references

Leave a Reply

Your email address will not be published. Required fields are marked *