Skip to content

BlueBubbles health check reports healthy during a full inbound outage (no iMessage liveness signal) #1459

Description

@njbrake

Note: this issue was drafted by Claude via back-and-forth with @njbrake. The reasoning and decisions are his; the prose is Claude's.

Summary

The BlueBubbles channel reports healthy as long as the BlueBubbles HTTP server responds. It has no signal for whether iMessage itself is actually registered and delivering. When iMessage stops delivering on the Mac or Apple side, inbound messages stop arriving entirely while Clawbolt continues to report the channel as configured and reachable.

What happened

A live deployment stopped receiving iMessages. Observations:

  • Messages sent to the assistant's iMessage address would not register as iMessage on the sender side (Apple was no longer advertising the address as reachable).
  • The BlueBubbles server itself was fully up the entire time: its HTTP landing page loaded and GET /api/v1/ping returned the expected 401 without a password.
  • Clawbolt's health check stayed green throughout, and is_bluebubbles_configured() continued to report the channel as configured and reachable.
  • The Mac was kept awake with Amphetamine and had run without issue for months, so display or system sleep was not the trigger.
  • Recovery was manual and entirely Apple side: sending an outbound iMessage from the account re-established delivery, after which inbound resumed.

Root cause (as far as it can be determined)

Two independent layers can fail while the BlueBubbles HTTP server stays reachable:

  1. macOS idling Messages on an inactive or headless Mac, so chat.db stops being written and inbound is never detected. Documented upstream in Inbound messages not being received after Mac innactivity BlueBubblesApp/bluebubbles-server#750; the recovery workaround noted there is to send an outbound message to wake Messages.
  2. The iMessage account deregistering on Apple's side, independent of Mac sleep. Recovery is to re-register by signing out and back in, or by sending an outbound message.

In both cases _check_server_reachable() in backend/app/channels/bluebubbles.py, which polls GET /api/v1/server/info, keeps returning success because the HTTP layer is alive. The messaging layer is dead but invisible to the app.

Impact

  • Inbound iMessages are dropped silently with no health signal.
  • Operators cannot distinguish "BlueBubbles server down" from "iMessage not delivering," which makes this slow to diagnose.

Proposed direction

  1. Add an iMessage liveness signal distinct from HTTP reachability. Candidates to investigate: query BlueBubbles for the Messages / Private API connection state if it exposes one, and track "no inbound received in N hours despite server reachable" as a degraded state.
  2. Surface the distinction (server reachable vs iMessage delivering vs no recent inbound) in the admin health surface, so it is visible before users report silence.
  3. Optional mitigation to document or ship: a periodic keepalive that sends an iMessage from the account to keep the Apple registration warm. This is a plausible mitigation, not a proven fix; the proven recovery is re-registration.

References

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions