Offline failures are easiest to diagnose when every app, schema, cache, synchronization, operating-system, and server change is tied to a reproducible device state. A change log narrows the search, but the decisive evidence comes from controlled transitions between online, degraded, airplane-mode, and restored-connectivity states.
Define what “offline” was supposed to mean
List the critical functions promised without a network: launch, sign-in state, reading cached data, creating or editing records, attachments, search, queueing, and later synchronization. Record app version, build, platform, device, operating-system version, account type, local database version, last successful sync, available storage, battery restrictions, and the exact connectivity transition.
Android's offline-first guidance says an offline-first app should at least be able to read critical data without network access and describes local sources of truth, queued reads and writes, retries, synchronization, metadata, and conflict resolution. Use the product's actual contract rather than assuming every feature must write offline.
Join the relevant change histories
Collect release notes, database migrations, serialization changes, cache keys, service-worker versions, API contracts, authentication updates, background-work changes, server deployments, feature flags, and operating-system policy changes. Normalize timestamps and identify the first known-good and first known-bad sessions.
For web apps, MDN's service-worker guide documents registration, installation, activation, cache storage, updates, and developer-tool inspection. Record both page version and controlling service-worker version; a newly deployed page can remain paired with an older active worker or cache.
Reproduce across a connectivity matrix
Test fresh install online, warm launch online, warm launch offline, offline write then reconnect, slow or intermittent network, captive portal, expired session, device restart, application update, and two-device conflict. Use invented records. Capture local state before and after each transition and label whether a record is pending, synchronized, conflicted, rejected, or permanently failed.
Do not rely on a network indicator alone. MDN's online-event documentation warns that an online state does not prove a particular server is reachable through a firewall or other network failure. Test the actual dependency with a bounded request and a clear timeout.
Inspect queues, retries, and conflicts
For every queued operation, record stable operation ID, entity ID, local version, intended action, creation time, attempt count, last error class, next retry, and acknowledgement. Distinguish authentication, validation, conflict, rate-limit, server, and connectivity failures because they need different recovery.
Android's persistent task scheduling documentation describes WorkManager constraints, unique work, persistence across restarts, monitoring, and retry or backoff policies. Verify that work is not silently duplicated, canceled, blocked by constraints, or retried forever. A queue length falling to zero is not success unless remote state and acknowledgement agree.
Bisect changes and repair one boundary
Rank changes by their contact with the failed boundary: local schema, cache format, auth token, request payload, conflict rule, background scheduler, or service-worker activation. Reproduce with the last known-good build against the current server and the current build against a compatible test server when safe. This separates client regression from server-contract change.
Apply the smallest reversible repair. Examples include migrating one schema, invalidating one cache namespace, correcting idempotency, classifying an error as non-retryable, or restoring a compatible API response. Preserve user data before any destructive cache or database action.
Verify recovery, not only reconnection
After the fix, verify offline launch, local read, permitted local write, visible pending state, restart persistence, controlled retry, conflict behavior, remote acknowledgement, duplicate prevention, and final consistency. Test accessibility of offline, pending, error, and conflict messages. Record unresolved queued operations and provide a user-safe recovery route.
Close the change log with the confirmed failure boundary, evidence, repair, rollback, test matrix, and monitoring signal. The problem is resolved only when the same user intent survives the offline transition and reaches one correct final state without hidden loss or duplication.
Sources
- Build an offline-first app — Android Developers
- Task scheduling — Android Developers
- Using Service Workers — MDN Web Docs
- Window: online event — MDN Web Docs