The setup: a bug that shouldn't exist
A UK user reported that our client's mobile app simply wouldn't work on mobile data. Over Wi-Fi, it was flawless. On other networks, flawless. The failure was confined to a single SIM card on a single UK carrier, and our development team was in India, with no direct access to the affected network.
It's the worst kind of bug: real, reproducible for exactly one person, and invisible to everyone trying to fix it. Every early signal pointed to "network connectivity", but other SIMs on the same phone, the same device settings, and the same app build all worked. Something was singling out this one carrier, and it wasn't the app or the server.
The investigation: ruling out every obvious cause
A methodical elimination. Each step: what we checked, and what we found.
Device and app settings
Had the user reinstall the app and compare network and device settings against working devices. No differences found.
Backend and infrastructure
Reviewed AWS security groups, VPC settings, firewall rules, IP whitelisting, and SSL certificate versions. No misconfiguration found.
Bypassing carrier DNS
Switched the device to public DNS (Google 8.8.8.8, Cloudflare 1.1.1.1) to rule out DNS-level blocking. The app still couldn't reach the API.
Routing through Cloudflare
Proxied all API traffic through Cloudflare to mask the origin and sidestep unknown carrier limitations. The backend domain loaded fine in a browser, but the mobile app still reported "No Internet Connection".
Every conventional cause was eliminated. The problem wasn't in our stack at all, it was in the network path, and it was deliberate.
Diagram: why the app saw "no internet"
The same request over Wi-Fi reaches the API cleanly. Over mobile data, the carrier's content filter intercepts the HTTPS request to the misclassified domain and silently drops the TLS connection, so the app sees a generic "no response" instead of a clear block.
- Wi-Fi path — HTTPS request reaches the API domain and returns normally.
- Mobile-data path — the carrier's content filter intercepts the request to the misclassified domain.
- Silent TLS reset — the connection is dropped, so the app only sees “no response”, not a block.
The carrier silently reset the TLS connection, so the app only saw “no response”.
Root cause: silent carrier content filtering
Carrier-level age/content filters
UK mobile networks apply content filters by default when they can't verify the subscriber is over 18. These network-level filters manifest as TLS connection resets or timeouts, so the user sees a generic "no response" rather than a clear "blocked" message. Originally applied to pay-as-you-go SIMs with no age evidence, they've since extended to contract phones that could be used by minors.
Domain misclassification
The client's API was hosted on a domain that had previously served objectionable content and been categorised under the BBFC's rules. Carriers maintain filtering lists based on a domain's history. When the user hit the API domain on mobile data, the carrier redirected the HTTPS request to an age-verification page, and when verification wasn't completed, dropped the TLS connection, producing the "timed out / no response" error.
Why manual verification doesn't scale
When the user manually completed the carrier's age-verification page in a browser, the app worked on that SIM. But that's unusable for a public consumer app: every new user would have to verify individually (killing sign-ups), it only unblocks one account at a time, and many carriers require a credit card or passport to lift the filter.
Diagram: the fix — a resilient domain & delivery strategy
The domain and delivery layer were re-engineered so carrier filtering can't silently break the app, with a fallback ready if it ever recurs.
Ready to switch instantly if the primary is ever misclassified, no app update needed.
- Clean .com domain — no filtering history, so carriers don't block it.
- Cloudflare — trusted TLS from a recognised provider, origin concealed.
- Fallback subdomain — points to the same backend, switchable without an app update.
A clean domain behind Cloudflare, with a fallback path and pre-launch filter checks.
The solution we engineered
Migrated to a clean domain
Purchased a new .com with no history of objectionable content, compliant with BBFC rules. Migrated the backend API and admin panel to it, behind Cloudflare, so TLS came from a trusted provider, the origin was concealed, and misclassification risk dropped.
Adopted a filter-safe naming scheme
Used widely recognised TLDs (.com, .org) over novelty ones; avoided suspicious keywords (xxx, adult, admin) in favour of neutral names like api.myrecruitapp.com; and hosted a simple legitimate landing page at the root, since carriers often check it. Before finalising, checked the domain's classification via Symantec Site Review (formerly Blue Coat WebPulse) and requested recategorisation where needed (updates take ~24–48h).
Contacted the carrier and the BBFC
Requested reclassification of the old domain, providing proof it now served a recruitment platform. Honestly, there's no clear published route for developers to reach carriers or the BBFC; we submitted generic support requests and followed up by phone, and reclassification can take weeks, during which a fallback is essential.
Built a subdomain fallback
Configured a secondary subdomain pointing to the same backend, so if a carrier ever misclassifies the primary domain, traffic can switch instantly without an app update.
Improved error handling
Updated the app (using @react-native-community/netinfo) to distinguish genuine connectivity loss from an unreachable server, and to show a meaningful message suggesting the user try another network or contact their carrier.
Added cross-network QA
QA now tests on major UK carriers (O2, EE, Vodafone, Three, giffgaff) in addition to Wi-Fi, so carrier-specific blocking is caught before deployment.
Outcome
After migrating to the clean domain and getting it whitelisted, users on all networks, including the previously blocked giffgaff/O2 SIMs, could use the app with no age-verification challenge. No further connectivity complaints were received. During the carrier-reclassification delay, the fallback domain kept the client's users connected instead of losing business to silent failures.
Key takeaways for CTOs and chief engineers
Carrier filters are an operational risk
Carriers may block domains on historical content or unverified subscriber age. These appear as silent TLS failures, easy to miss when testing only on Wi-Fi or one network.
Domain hygiene matters
Vet domains before attaching them to critical APIs. Use neutral names, trusted TLDs, and avoid reusing domains with questionable histories.
Plan for misclassification
Keep a fallback domain, monitor carrier blocking databases, and have a rapid domain-migration process and carrier/regulator contact points ready.
Design error states for the real cause
Clear connectivity checks and messages guide users to a workaround instead of leaving them stuck, improving trust and cutting support load.
Embed multi-carrier testing in QA
Test with SIMs from major carriers, especially in markets with strict content filtering.