Skip to content

AirTag (2nd generation) advertises a DULT payload instead of Offline Finding while near its owner #272

Description

@lonsdaleite

Summary

Near its owner, an AirTag (2nd generation) periodically stops sending the Apple Offline Finding advertisement (manufacturer data 0x004C, type 0x12) and sends the IETF DULT location-enabled payload instead. OfflineFindingScanner only looks at Apple manufacturer data, so during these periods the tag is invisible to local scanning even though its keys are known. The address of the DULT advertisement is derived from the same rolling key, so it can still be matched.

Observations

Two AirTag (2nd generation) tags on the same Apple Account, stationary at home with owner devices around (iOS 26.x, AirTag firmware 3.0.49). Captured with a raw HCI socket on a Linux host next to Home Assistant's Bluetooth stack, and matched against keys exported for FindMy.py.

  • DULT payload. The advertisement carries no Apple manufacturer data, only service data with the 16-bit UUID 0xFCB2:
    07 16 b2 fc 01 01 10 03    (tag A)
    07 16 b2 fc 01 01 14 00    (tag B)
    
    Per draft-ietf-dult-accessory-protocol this is the network ID (0x01, Apple), the near-owner bit (0x01), and proprietary data (last two bytes, meaning unknown).
  • Address. The address is a random static address equal to the first 6 bytes of the current primary key. The two most significant bits of the first byte are forced to 11 by the address type. (adv_key[0] | 0xC0) + adv_key[1:6] matched the observed address for the primary key at the current index.
  • Rotation. The address rotates every 15 minutes and on state changes.
  • The rest of the time, the same tags send the full Offline Finding payload (0x12, length 0x19) with the current primary key, not the daily secondary one.
  • Duration. DULT periods lasted from ~15–22 minutes to well over an hour. During them, not a single 0x12 advertisement was received for any key index 0–20000 of the tag, while original AirTags nearby kept sending 0x12 (nearby, length 0x02).
  • Original AirTags near the owner, in the same place, use the nearby Offline Finding format as usual. I have not seen DULT from them.

Impact

OfflineFindingScanner / is_from() cannot see second-generation AirTags while they are in the DULT state. Anything built on local scanning then reports the tag as gone for 15+ minutes at a time.

Possible approach

What I did in a Home Assistant integration: lonsdaleite/hass-FindMy@80590e4, match_dult_advertisement in local_bluetooth.py.

  • Parse service data 0000fcb2-0000-1000-8000-00805f9b34fb, require network ID 0x01, and read the near-owner bit.
  • Match the address against adv_key[:6] of the candidate keys with the two top bits of the first byte masked: adv_key[0] & 0x3F. This is like the nearby format, but without the two bits that nearby carries in its payload.
  • There is no status/battery byte in this payload.

Happy to test changes against these tags.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions