RevenueCat Network Error / Connection Failed
8:00What This Error Means
The NETWORK_ERROR (sometimes shown as "network connection lost" or "request timed out") means the RevenueCat SDK could not complete an HTTP request to the RevenueCat API servers, or the underlying App Store / Google Play Billing request failed due to connectivity. Unlike configuration errors, network errors are almost always transient — they reflect a temporary connectivity issue rather than a bug in your code.
Network errors can surface when the user is offline, when RevenueCat's servers experience an incident, or when something in the network path (ATS, VPN, firewall) is blocking the connection. The right response is to catch the error, inform the user, and offer a retry path — not to crash or permanently block the paywall.
Error Messages
# RevenueCat SDK (iOS and Android)
PurchasesError(code=NETWORK_ERROR, message="Network error")
# iOS URLSession (underlying transport)
Error: The network connection was lost. (NSURLErrorDomain error -1005)
Error: The request timed out. (NSURLErrorDomain error -1001)
Error: A server with the specified hostname could not be found. (NSURLErrorDomain error -1003)
# Android OkHttp / Retrofit (underlying transport)
java.net.SocketTimeoutException: timeout
java.net.UnknownHostException: Unable to resolve host "api.revenuecat.com"
java.io.IOException: Network is unreachable
# Flutter / React Native
PlatformException(NETWORK_ERROR, Network error, null, null)
RevenueCatError: NETWORK_ERROR (9) - Network error
Common Causes
-
Device is offline or on a poor connection
The most common cause by far. Cellular handoffs, entering a tunnel, or switching Wi-Fi networks can temporarily drop connectivity. RevenueCat API calls require an active internet connection to validate receipts and update entitlements.
-
RevenueCat API servers temporarily unreachable
Like all cloud services, RevenueCat occasionally experiences brief incidents. Check status.revenuecat.com during widespread or persistent network errors to see if there's an active incident. Most incidents resolve within minutes.
-
App Transport Security (ATS) blocking requests on iOS
iOS's ATS enforces strict HTTPS requirements. RevenueCat's API uses HTTPS exclusively, so it should not be blocked by default. However, if you've added custom
NSAppTransportSecurityentries in yourInfo.plistthat restrict all domains (e.g.,NSAllowsArbitraryLoads: NOcombined with a domain allowlist that doesn't include RevenueCat), you can inadvertently block the SDK. -
VPN or firewall blocking connections
Corporate VPNs, content filtering firewalls, or parental control software can block outbound HTTPS to RevenueCat's domains. This is most common in enterprise or education environments. Test on a different network (e.g., cellular data) to isolate this cause.
-
Emulator/Simulator has no network access
Android emulators and iOS simulators can sometimes lose their network connection after a host machine sleeps or changes networks. Restart the emulator or simulator and verify internet access by opening a browser inside it.
How to Handle Network Errors Gracefully
Network errors are expected in production apps. Your paywall and purchase flow should handle them without crashing or giving users a confusing experience. The following patterns demonstrate proper error handling with retry logic:
Swift — Error handling with retry
// Swift — Graceful network error handling
import RevenueCat
class PaywallViewModel: ObservableObject {
@Published var errorMessage: String?
@Published var isRetryable: Bool = false
func loadOfferings() {
Purchases.shared.getOfferings { [weak self] offerings, error in
DispatchQueue.main.async {
if let error = error as? RevenueCat.ErrorCode {
switch error {
case .networkError:
// Transient — offer retry
self?.errorMessage = "Connection failed. Please check your internet connection and try again."
self?.isRetryable = true
case .offlineConnectionError:
self?.errorMessage = "You appear to be offline. Connect to the internet to view subscription options."
self?.isRetryable = true
default:
// Non-network error — don't suggest retry
self?.errorMessage = "Something went wrong. Please restart the app."
self?.isRetryable = false
}
}
}
}
}
func purchase(_ package: Package) {
Purchases.shared.purchase(package: package) { transaction, customerInfo, error, userCancelled in
DispatchQueue.main.async {
if userCancelled { return }
if let error = error as? RevenueCat.ErrorCode, error == .networkError {
// Purchase may have gone through — always restore to check
self.restorePurchasesAfterNetworkError()
return
}
// Handle success or other errors...
}
}
}
private func restorePurchasesAfterNetworkError() {
// If the purchase call fails with a network error, the purchase may
// have been processed by the App Store but not confirmed by RevenueCat.
// Restoring purchases reconciles this state.
Purchases.shared.restorePurchases { customerInfo, error in
DispatchQueue.main.async {
if let activeEntitlement = customerInfo?.entitlements.active.first {
print("Entitlement restored: \(activeEntitlement.key)")
} else {
self.errorMessage = "Could not verify purchase. Please try again when connected."
self.isRetryable = true
}
}
}
}
}
Kotlin — Error handling with retry
// Kotlin — Graceful network error handling
import com.revenuecat.purchases.*
class PaywallViewModel : ViewModel() {
private val _errorMessage = MutableLiveData<String?>()
val errorMessage: LiveData<String?> = _errorMessage
private val _isRetryable = MutableLiveData(false)
val isRetryable: LiveData<Boolean> = _isRetryable
fun loadOfferings() {
Purchases.sharedInstance.getOfferingsWithCompletion(
onError = { error ->
when (error.code) {
PurchasesErrorCode.NetworkError -> {
_errorMessage.postValue(
"Connection failed. Check your internet connection and try again."
)
_isRetryable.postValue(true)
}
else -> {
_errorMessage.postValue("Something went wrong. Please restart the app.")
_isRetryable.postValue(false)
}
}
},
onSuccess = { offerings ->
// Handle successful offerings load
}
)
}
fun purchase(activity: Activity, packageToPurchase: Package) {
Purchases.sharedInstance.purchaseWith(
PurchaseParams.Builder(activity, packageToPurchase).build(),
onError = { error, userCancelled ->
if (userCancelled) return@purchaseWith
if (error.code == PurchasesErrorCode.NetworkError) {
// Restore purchases to reconcile potential App Store success
restorePurchasesAfterNetworkError()
}
},
onSuccess = { storeTransaction, customerInfo ->
// Handle successful purchase
}
)
}
private fun restorePurchasesAfterNetworkError() {
Purchases.sharedInstance.restorePurchasesWith(
onError = { error ->
_errorMessage.postValue("Could not verify purchase. Please retry when connected.")
_isRetryable.postValue(true)
},
onSuccess = { customerInfo ->
val activeEntitlements = customerInfo.entitlements.active
if (activeEntitlements.isNotEmpty()) {
Log.d("RevenueCat", "Purchase restored: ${activeEntitlements.keys}")
} else {
_errorMessage.postValue("No active purchases found. Please retry.")
_isRetryable.postValue(true)
}
}
)
}
}
NETWORK_ERROR, the charge may or may not have been processed by the App Store/Google Play. Always call restorePurchases() after a network error during checkout to ensure the customer receives their entitlement if the purchase did go through.
Debugging Steps
If users are consistently reporting network errors (not just transient ones), work through these steps to identify the root cause:
1. Verify device connectivity
Confirm the device has internet access before calling RevenueCat APIs. Use the system's network reachability APIs to gate purchases behind a connectivity check:
// Swift — Quick connectivity check using NWPathMonitor
import Network
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
print("Connected — safe to call RevenueCat APIs")
} else {
print("Not connected — show offline message to user")
}
}
monitor.start(queue: DispatchQueue.global())
2. Check the RevenueCat status page
Visit status.revenuecat.com to check for active incidents. Subscribe to incident notifications to be alerted of future service disruptions.
3. Test on different networks
If you only see the error on one specific network (e.g., corporate Wi-Fi but not cellular), this points to a firewall or proxy issue. Test on cellular data, a home network, and a hotspot to isolate network-specific problems.
4. Check ATS settings in Info.plist (iOS)
<!-- Info.plist — Do NOT add NSAllowsArbitraryLoads
RevenueCat uses HTTPS and does not need ATS exceptions.
If you have a domain allowlist, ensure it does not accidentally
block api.revenuecat.com -->
<!-- CORRECT: No ATS overrides needed for RevenueCat -->
<!-- INCORRECT: This would block all domains not listed, including RevenueCat -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSExceptionDomains</key>
<dict>
<!-- Only listing your own domain without including RevenueCat -->
<key>myapp.com</key>
<dict>...</dict>
</dict>
</dict>
5. Enable verbose logging to capture the full error
RevenueCat's debug logs include the HTTP status code and response body for failed requests, which makes it much easier to diagnose network errors:
// Enable before configure() to capture all network traffic in logs
Purchases.logLevel = .verbose
Purchases.configure(withAPIKey: "appl_YOUR_KEY")
// In the console, look for lines like:
// [Purchases] - DEBUG: Network request to GET https://api.revenuecat.com/...
// [Purchases] - ERROR: Network error: The network connection was lost.
// Enable before configure() — use VERBOSE for full network details
Purchases.logLevel = LogLevel.VERBOSE
Purchases.configure(
PurchasesConfiguration.Builder(this, "goog_YOUR_KEY").build()
)
// In Logcat, filter by tag "RevenueCat" and look for:
// D/RevenueCat: Network request to GET https://api.revenuecat.com/...
// E/RevenueCat: Network error: java.net.SocketTimeoutException
Related Guides
- iOS In-App Purchases Tutorial — Full iOS integration guide including error handling patterns
- Android In-App Billing Tutorial — Full Android integration guide including error handling patterns
- RevenueCat Troubleshooting Guide — Comprehensive troubleshooting for all RevenueCat integration issues
- SDK Debug Messages — How to read RevenueCat debug log output to diagnose network and other errors
- General Debugging Tips — Broad debugging strategies for RevenueCat integration issues