SDK Debug Messages
0:05:00Understanding SDK debug messages is crucial for troubleshooting. This section explains how to enable logging and interpret common log messages.
Enabling Debug Logging
Always enable verbose logging during development to see what the SDK is doing.
iOS (Swift)
swift
import RevenueCat
// Enable before configure
Purchases.logLevel = .debug // Most verbose
// Purchases.logLevel = .verbose // Alternative
Purchases.configure(withAPIKey: "appl_xxx")Android (Kotlin)
kotlin
import com.revenuecat.purchases.LogLevel
// Enable before configure
Purchases.logLevel = LogLevel.DEBUG // Most verbose
// Purchases.logLevel = LogLevel.VERBOSE // Alternative
val builder = PurchasesConfiguration.Builder(this, "goog_xxx")
Purchases.configure(builder.build())Log Levels
- DEBUG: Most verbose, shows everything (use during development).
- VERBOSE: Detailed information about operations.
- INFO: General informational messages.
- WARN: Warnings about potential issues.
- ERROR: Error messages only.
Production: Set log level to
.warn or .error in production to avoid performance overhead and log clutter.
Common Warning Messages
Warning: Products Not Approved (iOS)
text
[RevenueCat] Warning: RevenueCat SDK is configured correctly, but contains some issues you might want to address
Warnings:
• Your products are configured in RevenueCat but aren't approved in App Store Connect yet.
This prevents users from making purchases in production.
Please ensure all products are approved and available for sale in App Store Connect.What it means:
- Products exist in RevenueCat dashboard.
- But they're not approved in App Store Connect.
- This is normal during development.
Action required:
- If testing: Use StoreKit Configuration File or wait for approval.
- If production: Submit products for review with your app.
- Can be safely ignored during local development.
Warning: Offering Configuration Issues
text
[RevenueCat] Warning: The offerings 'default' have configuration issues that may prevent users from
seeing product options or making purchases.
Product Issues:
• Package 'monthly' references product 'premium_monthly' which is not available
• Package 'annual' references product 'premium_annual' which is not availableWhat it means:
- Packages in offering reference products that can't be found.
- Products might not exist in store or IDs don't match.
Action required:
- Verify product IDs match between RevenueCat and store.
- Check products are active/approved in store.
- Ensure products are added to StoreKit Configuration (iOS).
Common Error Messages
Error: None of Products Could Be Fetched
text
[RevenueCat] Error fetching offerings - The operation couldn't be completed.
(RevenueCat.OfferingsManager.Error error 1.)
There's a problem with your configuration. None of the products registered in the RevenueCat dashboard
could be fetched from App Store Connect (or the StoreKit Configuration file if one is being used).
More information: https://rev.cat/why-are-offerings-emptyWhat it means:
- SDK tried to fetch products from store but all failed.
- Critical configuration issue.
Action required:
- Check product IDs match exactly.
- Verify bundle ID/package name matches.
- For iOS: Use StoreKit Configuration or wait for product approval.
- For Android: Verify service account permissions.
See the Fetching Offerings Errors section above for detailed troubleshooting.
Error: Network/API Issues
text
[RevenueCat] Error: Unable to fetch offerings
NetworkError: The Internet connection appears to be offline
URLError: The request timed outWhat it means:
- Device has no network connection.
- Or RevenueCat servers are unreachable.
Action required:
- Check device internet connection.
- Test if other apps/websites work.
- Disable VPN if using one.
- Implement retry logic in your app.
Error: Invalid API Key
text
[RevenueCat] Error: Invalid API key
The API key provided is invalid or doesn't have access to this appWhat it means:
- API key is wrong or typo.
- Using wrong platform key (iOS key on Android or vice versa).
Action required:
- Go to RevenueCat dashboard → API keys.
- Copy the correct key for your platform:
- iOS: Starts with
appl_. - Android: Starts with
goog_.
- iOS: Starts with
- Update your code.
Understanding Store Error Codes
iOS StoreKit Error Codes
| Code | Name | Meaning |
|---|---|---|
| 0 | unknown | Unknown or unexpected error |
| 1 | clientInvalid | Client is not allowed to make request |
| 2 | paymentCancelled | User cancelled the purchase |
| 3 | paymentInvalid | Purchase identifier is invalid |
| 4 | paymentNotAllowed | Device not allowed to make payments |
| 5 | storeProductNotAvailable | Product not available in store |
Android Billing Response Codes
| Code | Name | Meaning |
|---|---|---|
| 0 | OK | Success |
| 1 | USER_CANCELED | User cancelled the purchase |
| 2 | SERVICE_UNAVAILABLE | Network connection is down |
| 3 | BILLING_UNAVAILABLE | Billing API version not supported |
| 4 | ITEM_UNAVAILABLE | Product not available for purchase |
| 5 | DEVELOPER_ERROR | Invalid arguments to API |
| 6 | ERROR | Fatal error during API action |
| 7 | ITEM_ALREADY_OWNED | User already owns this item |
| 8 | ITEM_NOT_OWNED | User doesn't own item (restore) |
Interpreting Purchase Flow Logs
Here's what a successful purchase flow looks like in logs:
text
[RevenueCat] DEBUG: Fetching offerings from cache
[RevenueCat] DEBUG: Offerings retrieved successfully
[RevenueCat] DEBUG: makePurchase called for package: monthly
[RevenueCat] DEBUG: Starting purchase flow for product: premium_monthly
[RevenueCat] DEBUG: Purchase initiated
[RevenueCat] DEBUG: Finishing purchase transaction
[RevenueCat] DEBUG: Transaction finished successfully
[RevenueCat] INFO: Purchase completed successfully
[RevenueCat] DEBUG: CustomerInfo updatedKey points:
- Shows full purchase lifecycle.
- Transaction finishes automatically.
- CustomerInfo updates after purchase.
Common SDK Messages Quick Reference
| Log Message | What It Means | Action Required |
|---|---|---|
| "Products not approved in App Store" | RevenueCat found products in the dashboard, but they aren't approved by Apple yet. | This is normal during development. Use a StoreKit Configuration File for local testing, or submit products for review with your app binary. Can be safely ignored while developing. |
| "Offering configuration issue" | A package references a product that can't be found in the store. | Verify product IDs match between RevenueCat and the store. Check that products are active (Android) or approved (iOS). Remove any orphaned product references from your offering. |
| "None of the products registered" | All products failed to load from the store. Critical configuration error. | Check product IDs, bundle ID/package name, API key, and store account status. Enable logLevel = .debug for detailed info. This is the most common integration error. |
| "Error performing request" | Network request to RevenueCat API failed. | Check internet connectivity. Disable VPN/proxy temporarily. Verify api.revenuecat.com is reachable. The SDK will retry automatically with exponential backoff for transient failures. |
| "Invalid API Key" | The API key passed to Purchases.configure() is invalid or for the wrong platform. |
Go to RevenueCat dashboard → API keys. Copy the correct key: appl_ for iOS, goog_ for Android. Ensure no extra spaces or characters were added when copying. |
| "There is already a configure call" | SDK is being configured more than once in the app lifecycle. | Call Purchases.configure() only once, typically in AppDelegate (iOS) or Application.onCreate() (Android). Check for duplicate calls in different app entry points (e.g., SceneDelegate, SwiftUI App init). |
| "Finishing transaction" | Normal SDK behavior. The SDK is completing a store transaction. | No action needed. This is expected after a successful purchase. If you see this without a corresponding purchase, it may be finishing a previously unfinished transaction. |
| "CustomerInfo updated" | The user's entitlement status has changed. | No action needed. This is normal after purchases, restores, or subscription changes. Your CustomerInfo listener should receive this update to refresh UI. |
| SKError Code 0 (unknown) | StoreKit returned an unknown error on iOS. | Often a transient issue. Retry the operation. If persistent, check Apple's System Status. Try signing out and back into the sandbox account on the device. |
| SKError Code 2 (paymentCancelled) | User cancelled the purchase dialog. | No action needed. Handle gracefully in your app by not showing an error message. The user chose not to proceed with the purchase. |
| BillingResponseCode 1 (USER_CANCELED) | User dismissed the Google Play purchase dialog. | No action needed. Same as iOS cancellation. Handle gracefully and let the user try again when ready. |
| BillingResponseCode 3 (BILLING_UNAVAILABLE) | Google Play Billing is not available on the device. | Verify device has Google Play Store installed and updated. Check the device has a Google account signed in. Emulators must use a "Google Play" system image, not just "Google APIs". |
| BillingResponseCode 5 (DEVELOPER_ERROR) | Invalid arguments or misconfigured app on Google Play. | Verify package name matches, app is published to a testing track, and product IDs exist. This often means the Google Play Console configuration doesn't match your app's build. |
| "Purchases not completed" | A purchase started but never finished. | Ensure your app stays in the foreground during purchase. On Android, check that the Activity isn't being recreated. On iOS, ensure the purchase callback isn't blocked by a UI thread operation. |
| ConfigurationError Code 23 | Generic configuration wrapper. The underlying error contains the real cause. | Log the complete error object (JSON.stringify(e) or check userInfo) to reveal the underlying error. Common causes include product ID mismatches, missing backwards compatibility on Google Play, and unsigned agreements. See community discussion. |
| "BillingClient is not connected yet" | SDK queries Play Store before BillingClient finishes connecting. | The SDK handles reconnection automatically. Ensure Google Play Services is updated on the device. Do not fetch offerings immediately after configure(). Update to the latest SDK version which has improved connection handling. See community discussion. |
| Entitlements lost after login/logout | Purchase attached to anonymous ID, not carried over after logIn(). |
Call Purchases.logIn() with the user's ID immediately after authentication, before any purchases. Implement syncPurchases() after auth state changes. Prompt users to "Restore Purchases" as a fallback. See community discussion. |
Granted entitlement not in getCustomerInfo() |
SDK cache not refreshed after server-side entitlement grant. | Call Purchases.shared.invalidateCustomerInfoCache() before getCustomerInfo() to force a fresh fetch. The SDK caches customer info for 5 minutes. Server-side changes (like promotional grants) require a cache clear. See community discussion. |
Tips for Effective Debugging
- Always enable debug logging first when troubleshooting.
- Search logs for "RevenueCat" to filter SDK messages.
- Look for error and warning symbols to find errors/warnings quickly.
- Check logs immediately after operations (fetch offerings, purchase, restore).
- Copy full error messages when asking for support.
- Disable in production to avoid performance issues.