home-assistant / home-assistant/core
iCloud device_tracker location frozen after startup (battery still updates) — pyicloud ≥2.3.0 no longer locates implicitly
- Dominant language
- Python
- Stars
- 90.5k
- Forks
- 38.6k
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 597
Description
### The problem
The iCloud integration's `device_tracker` entities stop receiving fresh GPS locations after Home Assistant starts: the coordinates (and `gps_accuracy`, bit-for-bit identical float) stay frozen for hours or days, while the battery sensors of the same devices update correctly on every poll. In my recorder history a phone's iCloud tracker kept the exact same lat/lon/accuracy for ~10 hours across two real-world trips (a companion-app tracker on the same phone followed the trips correctly), then jumped to the correct position immediately after an HA restart.
Root cause: a behavior change in pyicloud 2.3.0 (PR timlaing/pyicloud#175). Before it, `AppleDevice.status()`/`.location` implicitly called `refresh_client()` which always sent `"shouldLocate": true`, so every `IcloudAccount.update_devices()` poll actively located the devices — that is what the integration has relied on since the pyicloud 1.x days. Since 2.3.0, reads are pure cache reads and the library's background monitor thread refreshes with `locate=False`; the only active locate happens once when the service is constructed (i.e. at HA startup / integration reload). Apple then keeps serving its cached location blob — battery stays fresh (devices push status to Apple on their own), GPS never refreshes. Reported upstream too: timlaing/pyicloud#360.
The bug therefore ships in every HA release since the pyicloud 2.3.0 bump (#161164, HA 2026.2). It is completely silent — no errors, nothing in logs.
Fix: call the (since pyicloud 2.x) public `refresh(locate=True)` in `IcloudAccount.update_devices()` before reading device status. One-line change; I have been running it in production and the very next poll after deploying it un-froze the stale trackers (fresh accuracy values on every subsequent poll, device correctly moved into the right zone). PR incoming.
### What version of Home Assistant Core has the issue?
core-2026.9.1 (present since core-2026.2, the pyicloud 2.3.0 bump)
### What was the last working version of Home Assistant Core?
core-2026.1.x
### What type of installation are you running?
Home Assistant Container
### Integration causing the issue
Apple iCloud
### Link to integration documentation on our website
https://www.home-assistant.io/integrations/icloud
### Diagnostics information
_No response_
### Example YAML snippet
_No response_
### Anything in the logs that might be useful for us?
```txt
Nothing - the failure is silent. Recorder history shows the symptom (battery changes each
30-min poll, GPS bit-for-bit identical):
09:28:07 lat=50.72648 lon=23.25166 gps_accuracy=9.280551647491146 battery=87
08:58:07 lat=50.72648 lon=23.25166 gps_accuracy=9.280551647491146 battery=97
08:28:06 lat=50.72648 lon=23.25166 gps_accuracy=9.280551647491146 battery=74
07:58:06 lat=50.72648 lon=23.25166 gps_accuracy=9.280551647491146 battery=62
```
### Additional information
Timeline of the regression:
- pyicloud 1.0.0 → 2.2.0: `AppleDevice.status()` / `.location` refreshed with `shouldLocate: true` on every access → each `update_devices()` poll actively located devices.
- pyicloud PR timlaing/pyicloud#175 (released in 2.3.0): removed the implicit refresh from `status()`/`location` and moved refreshing to a background thread that never passes `locate=True`.
- HA #161164 bumped to pyicloud 2.3.0 (core-2026.2) → locations freeze after startup for all users of this integration.
Contributor guide
Assessment
This issue has not been assessed yet.