Why Bluetooth addresses change: MAC randomization explained
Run a scan for ten minutes and you'll collect far more addresses than there are devices in the room. Scan the same drawer twice an hour apart and nothing matches. The obvious conclusion is that your scanner is broken or the neighborhood is unusually busy.
Neither. Most modern BLE devices deliberately change their address on a timer, precisely so you can't do what you're trying to do. This guide explains the mechanism, how to identify which kind of address you're looking at, and what you can still track across the changes.
Why it exists
A Bluetooth address is 48 bits and, historically, permanent — burned in at the factory like an Ethernet MAC. A permanent identifier that a device broadcasts continuously, unencrypted, several times per second, is a tracking beacon. Anyone with a $5 receiver could log who walked past.
That was the situation with early BLE, and it was exploited: retailers built shopper-tracking networks out of nothing but passive Bluetooth scanners. Bluetooth 4.2 introduced LE Privacy to close it, and it's now the default on every major platform.
The four address types
A BLE address is either public or random, signaled by a flag in the packet alongside the address itself. Random splits into three sub-types, and you can tell them apart from the top two bits of the most significant byte:
| Type | Top 2 bits | Lifetime |
|---|---|---|
| Public | n/a (flagged separately) | Permanent |
| Random static | 11 |
Fixed until reboot |
| Resolvable private (RPA) | 01 |
Rotates, typically ≤15 min |
| Non-resolvable private | 00 |
Rotates, no way to link |
Note that 10 is not a valid random address prefix.
Public
A globally unique, IEEE-registered address that never changes. The first three bytes identify the manufacturer — the same OUI system as Ethernet — which makes public addresses genuinely useful for identifying an unknown device. These days you mostly see them on development boards, older hardware, and devices whose designers didn't consider privacy.
Random static
Random, but fixed for as long as the device stays powered. It changes on reboot and not otherwise. Plenty of sensors and beacons use this: it avoids shipping a registered address while still being stable enough to reconnect to.
For scanning purposes a random static address behaves like a permanent one, so long as nothing power-cycles.
Resolvable private address (RPA)
This is the one causing your duplicates. An RPA is regenerated on a timer — the specification recommends no longer than 15 minutes, and most stacks use exactly that.
It isn't purely random. The 48 bits split into two halves:
[ prand : 24 bits ] [ hash : 24 bits ]
^ top two bits are 01 ^ hash = ah(IRK, prand)
The device picks 22 random bits, prefixes them with 01, then computes a 24-bit hash of that value
using its Identity Resolving Key (IRK) — a secret it hands out only when you bond with it.
The consequence is the clever part: anyone holding the IRK can take a fresh RPA, recompute the hash from the prand half, and confirm it belongs to a known device. Anyone without the IRK sees 48 bits of noise. Your phone silently re-recognizes your own earbuds across every rotation, while a passive scanner nearby sees an endless parade of strangers.
Non-resolvable private address
Fully random with a 00 prefix and no recoverable relationship to the device. Nobody can link it,
including the device's own owner. It's rare, used mostly for beacons that broadcast without ever
expecting a connection.
What this means for scanning
Address-based deduplication does not work. If your scan list is keyed on address, one pair of headphones sitting in a drawer for an hour becomes four to six entries.
What you can key on instead, roughly in order of reliability:
- Complete or shortened local name. Frequently stable across rotations, because the name lives in the advertising payload rather than the header. Not always present, and not unique — every device of a model may share it.
- Service UUIDs. The set of advertised services is usually identical across rotations. Good for grouping by device type; weak for telling two identical sensors apart.
- Manufacturer-specific data. Sometimes contains a genuinely stable serial or ID — and sometimes contains a counter that rotates alongside the address. Worth decoding to find out; you can paste a payload into the decoder to see what a device is actually putting in there.
- A fingerprint of several fields together. Name plus service list plus payload length plus advertising interval is a reasonably distinctive signature, and in practice it's the most effective approach available to a passive scanner.
- RSSI continuity. Weak on its own, but a new address appearing at the same signal strength in the same second an old one disappeared is suggestive. See RSSI to distance for how noisy that signal is.
None of these are guaranteed. A device that rotates its address and varies its payload is, by design, untrackable from outside — and that is the feature working correctly.
The tracker-detection wrinkle
Address rotation is why finding a hidden tracker is harder than it sounds, and why the manufacturers' own alerts exist. An AirTag separated from its owner rotates its address like everything else, so you can't simply watch for a familiar address following you between locations.
Apple's and Google's detection systems work because those devices also broadcast a platform-specific service that the OS recognizes — a signal that says "I am a tracker of this type," independent of the address. A general BLE scanner can see that same service data, which is what makes third-party scanning useful even against rotating addresses. The full method is in how to find a hidden Bluetooth tracker.
Platform differences
On Android you get the address, its type, and the rotation is visible to you as it happens.
On iOS you never see an address at all. Core Bluetooth substitutes a per-app UUID of its own, which papers over rotation for connected devices but introduces a different set of limits. Those are covered in BLE scanning on iPhone.
Watching it happen
The rotation is easy to observe if you log rather than glance. Leave a scan running for half an hour next to a device you control, export the log, and sort by name: you'll see one name attached to a series of unrelated addresses at roughly quarter-hour boundaries.
BLE Sniffer for Android records the address type alongside each packet and exports to CSV, which makes the pattern obvious once you have a few rotations captured.
Related reading
- How BLE advertising works — the payload that survives an address change
- How to identify an unknown Bluetooth device — working out what something is without a stable address
- What is a BLE sniffer? — what passive scanning can and cannot see