ο»Ώ

This section assumes you've followed our [Quickstart](πŸ”—ο»Ώ) section of our Getting Started guide to install and configure our SDK.

# Error Handling

If the completion callbacks or listeners on asynchronous methods receive an error argument that is not nil, an error has occurred.

With the exception of `NetworkError`, `PurchaseCancelledError` or `StoreProblemError`, retrying a failed operation with the same arguments won't succeed. For failed purchases, assume the user wasn't charged, unless a `StoreProblemError` occurred - in which case the user may or may not have been charged.

## iOS Errors

On iOS, when an error has occurred the completion callback will receive a `RevenueCat.ErrorCode` object.

When investigating or logging errors, review the `errorUserInfo` dictionary, paying attention to the following keys:

  • `rc_code_name` contains a cross-platform error name string that can be used for identifying the error.

  • `NSDebugDescriptionErrorKey` contains a description of the error. This description is meant for the developer.

### Examples

ο»Ώ

## Android Errors

On Android, when an error has occurred, the `onError` listener will receive a `PurchasesError` object.

When investigating or logging errors, review the properties of `PurchasesError`:

  • `code` contains the `PurchasesErrorCode` that can be used for identifying the error.

  • `message` contains a description of the error. This description is meant for the developer.

  • `underlyingErrorMessage ` contains a description of the underlying error that caused the error in question, if an underlying error is present.

### Examples

ο»Ώ

# Legend

When debugging errors, it's important to consider whether the error was thrown by RevenueCat, Apple, or Google. This can help you pinpoint where to look for a resolution.

IconDescription
😿Error generated from RevenueCat
🍎Error generated from Apple
πŸ€–Error generated from Google
πŸ“¦Error generated from Amazon

# Error codes common to all methods

#### 😿 `INVALID_APP_USER_ID`

**Problem:** Indicates the [App User Id](πŸ”—ο»Ώ) is set to an invalid value.

**Resolution:** Make sure you're not sending a string over 100 characters or a [blocked app user Id](πŸ”—ο»Ώ).


ο»Ώ

#### 😿 🍎 πŸ€– πŸ“¦ `INVALID_CREDENTIALS`

**Problem:** Indicates the application has been configured with an invalid credentials.

**Resolution:** If this error occurs before a purchase, ensure you're using the [correct API Key](πŸ”—ο»Ώ) from the RevenueCat dashboard. If this error happens during the purchase flow, make sure your [Play Store Credentials](πŸ”—ο»Ώ) and/or [App Store Shared Secret](πŸ”—ο»Ώ) and/or [Amazon Appstore Credentials](πŸ”—ο»Ώ) are configured correctly in the RevenueCat dashboard.


ο»Ώ

#### 😿 `INVALID_SUBSCRIBER_ATTRIBUTES`

**Problem:** Indicates subscriber attributes were unable to be saved.

**Resolution:** Make sure that there are no formatting issues when [setting subscriber attributes](πŸ”—ο»Ώ).


ο»Ώ

#### 😿 `NETWORK_ERROR`

**Problem:** Indicates a network error occurred during the operation.

**Resolution:** Make sure the device has an internet connection and try again. If you are testing in sandbox, make sure your outgoing connections is turned on. You can find this in XCode under signing & capabilities > App Sandbox > Outgoing connections (Client).


ο»Ώ

#### 😿 `OFFLINE_CONNECTION_ERROR`

**Problem:** Indicates the device was offline when attempting a network request.

**Resolution:** Make sure the device has an internet connection and try again.


ο»Ώ

#### 😿 `OPERATION_ALREADY_IN_PROGRESS`

**Problem:** Indicates an identical operation is already in progress. For example, making two identical purchase attempts at the same time.

**Resolution:** Wait for the original operation to complete.


ο»Ώ

#### 🍎 πŸ€– πŸ“¦ `STORE_PROBLEM`

**Problem:** This error is forwarded from Apple/Google/Amazon and indicates there was a problem connecting to the App Store, Play Store, or Amazon Appstore.

The problems that will trigger this on iOS:

  • Apple server is down (more common in sandbox than production)

  • ο»Ώ[SKErrorUnknown](πŸ”—ο»Ώ)ο»Ώ

  • ο»Ώ[SKErrorCloudServiceNetworkConnectionFailed](πŸ”—ο»Ώ)ο»Ώ

  • ο»Ώ[SKErrorCloudServiceRevoked](πŸ”—ο»Ώ)ο»Ώ

  • An [SCA purchase flow](πŸ”—ο»Ώ) was initiated.

The problems that will trigger this on Android:

  • Google server is down

  • ο»Ώ[Google Play Developer API Quota exceeded](πŸ”—ο»Ώ)ο»Ώ

  • Invalid Android package name in the RevenueCat dashboard

  • Google Billing Client [SERVICE_TIMEOUT](πŸ”—ο»Ώ) error

**Resolution:** If everything was working while testing, you shouldn't have to do anything to handle this error in production. RevenueCat will automatically retry any purchase failures so no data is lost.

If this occurs while testing in sandbox you can try:

  • Repeating the operation later.

  • Create a new sandbox user on iOS.


ο»Ώ

#### 🀷 `SIGNATURE_VERIFICATION_FAILED`

**Problem:** Indicates that the SDK detected a request was tampered.

**Resolution:**

  • Ensure that a proxy is not modifying responses from our API.

  • See [the docs](πŸ”—ο»Ώ) for more information.


ο»Ώ

#### 😿 `UNEXPECTED_BACKEND_RESPONSE_ERROR`

**Problem:** Indicates the SDK received an unexpected response from the server.

**iOS sub error codes:**

  • `loginResponseDecoding`: Unable to decode response returned from login.

  • `postOfferIdBadResponse`: Unable to decode response returned from posting offer for signing.

  • `postOfferIdMissingOffersInResponse`: Missing offers from response returned from posting offer for signing.

  • `postOfferIdSignature`: Signature error encountered in response returned from posting offer for signing.

  • `getOfferUnexpectedResponse`: Unknown error encountered while getting offerings.

  • `customerInfoNil`: Unable to instantiate a CustomerInfoResponse, CustomerInfo in response was nil.

  • `customerInfoResponseParsing`: Unable to instantiate a CustomerInfoResponse due to malformed json.

**Resolution:** [Report the error](πŸ”—ο»Ώ) with the full error object.


ο»Ώ

#### 😿 `UNKNOWN_BACKEND_ERROR`

**Problem:** Indicates there was an unknown server error.

**Resolution:** [Report the error](πŸ”—ο»Ώ) with the full error object.


ο»Ώ

#### 🀷 `UNKNOWN`

**Problem:** Indicates an unknown error occurred. Possible causes:

  • The subscriber has reached the maximum number of Apple receipts allowed. This can be an indication of an implementation error regarding identifying users. Take a look at our [best practices for identifying users](πŸ”—ο»Ώ) for common implementation mistakes.

**Resolution:** Help us [fix it](πŸ”—ο»Ώ).


ο»Ώ

# Purchasing Errors

#### 😿 `RECEIPT_ALREADY_IN_USE`

**Problem:** Indicates there is an identical receipt already in use by another subscriber.

**Resolution:** The user will either need to log in as the App User Id that already owns the receipt or [restore purchases](πŸ”—ο»Ώ) to re-sync the receipt with their current account. We recommend checking out the ['Transfer purchases'](πŸ”—ο»Ώ) restore behavior.


ο»Ώ

#### 🍎 πŸ€– πŸ“¦ `INVALID_RECEIPT`

**Problem:** Indicates the receipt is malformed or invalid.

**Resolution:** This error indicates an error with configuration and usually occurs in the sandbox environment.

If testing with StoreKit Configuration Files:

  • Follow [StoreKit test guide](πŸ”—ο»Ώ)

  • Re-upload the StoreKit certificate after making any changes to products or code-signing

  • All products in StoreKit file are listed in the [RevenueCat dashboard](πŸ”—ο»Ώ)ο»Ώ

Some other places to check:

  • Bundle ID and [shared secret](πŸ”—ο»Ώ) are set correctly for your app


ο»Ώ

#### 🍎 `INVALID_APPLE_SUBSCRIPTION_KEY`

**Problem:** Indicates that the Apple Subscription Key is invalid or not present.

**Resolution:** In order to provide Subscription Offers you must first generate a [subscription key](πŸ”—ο»Ώ).


ο»Ώ

#### 🍎 `MISSING_RECEIPT_FILE`

**Problem:** Indicates there is no receipt file available on the device. This is more common in sandbox testing.

**Resolution:** Make sure you're signed into the device with a valid Apple account. In Sandbox, you may have to make a purchase to generate a receipt before attempting the operation. This error can occur fairly often in the sandbox environment. In sandbox a receipt is generated when a user makes a purchase and is saved against the sandbox account. While in production a receipt is generated when a user downloads the app and is saved against the Apple account.


ο»Ώ

#### 🍎 `INELIGIBLE_ERROR`

**Problem:** Indicates that the user is ineligible for the specific Subscription Offer.

Some possible causes:

  • User has already used this Offer

  • Offer not available in specific region

  • User has no current or previous subscription

**Resolution:** If a user is not eligible for a Subscription Offer, be sure to update your UI to reflect normal pricing or terms. [`.paymentDiscount(...)`](πŸ”—ο»Ώ) is the best way to check for Subscription Offer eligibility. If you are testing in sandbox and already tested a purchase with that offer, you may want to [create a new sandbox user](πŸ”—ο»Ώ) to try again.


ο»Ώ

#### 🍎 πŸ€– `INSUFFICIENT_PERMISSIONS_ERROR`

**Problem:** Indicates the device does not have sufficient permissions to make in-app purchases.

**Resolution:** Make sure you're signed into a physical device with a valid Apple or Google account that has permissions to make purchases.


ο»Ώ

#### 🍎 πŸ€– `PAYMENT_PENDING_ERROR`

**Problem:** Additional action is required by the user before granting entitlement. For example, a user might choose to purchase your in-app product at a physical store using cash, or a parental control on a child's device may require approval before purchasing.

**Resolution:** Confirm to the user that they've started the pending purchase, and to complete it, they should follow instructions that are given to them from Apple or Google.


ο»Ώ

#### 🍎 `PRODUCT_ALREADY_PURCHASED`

#### πŸ€– `ITEM_ALREADY_OWNED`

**Problem:** Indicates that the product is already active for the user.

**Resolution:** If testing in sandbox:

  • Subscription IAP: Wait for the subscription to automatically cancel and try again.

  • Non-subscription IAP: Create a new sandbox user.

If this occurs in production, make sure the user [restores purchases](πŸ”—ο»Ώ) to re-sync any transactions with their current App User Id.


ο»Ώ

#### 🍎 `PRODUCT_NOT_AVAILABLE_FOR_PURCHASE`

#### πŸ€– `ITEM_UNAVAILABLE`

**Problem:** Indicates the product is not available for purchase by the device or user.

**Resolution:** Ensure you're attempting to purchase a product that's available for the device / user.


ο»Ώ

#### 🍎 πŸ€– `PURCHASE_CANCELLED`

**Problem:** Indicates the user cancelled their purchase and was not charged.

On iOS, this can also mean the Apple account already owns the product. The user can [restore purchases](πŸ”—ο»Ώ) to re-sync any transactions with their current App User Id.

**Resolution:** No action required. The user decided not to proceed with their in-app purchase.


ο»Ώ

#### 🍎 πŸ“¦ `PURCHASE_INVALID`

#### πŸ€– `DEVELOPER_ERROR`

**Problem:** Indicates one of the provided arguments for the purchase was invalid, including the payment method.

The problems that will trigger this on Android:

  • Google Billing Client [DEVELOPER_ERROR](πŸ”—ο»Ώ)ο»Ώ

The problems that will trigger this on iOS:

  • ο»Ώ[SKErrorInvalidOfferIdentifier](πŸ”—ο»Ώ)ο»Ώ

**Resolution:** Ensure the device payment method is valid and all arguments passed in are correct.


ο»Ώ

#### 🍎 πŸ€– `PURCHASE_NOT_ALLOWED`

**Problem:** Indicates the device or user is not allowed to make the purchase.

The problems that will trigger this on Android:

  • Google Billing Client [FEATURE_NOT_SUPPORTED](πŸ”—ο»Ώ)ο»Ώ

The problems that will trigger this on iOS:

  • ο»Ώ[SKErrorPrivacyAcknowledgementRequired](πŸ”—ο»Ώ)ο»Ώ

  • ο»Ώ[SKErrorPaymentNotAllowed](πŸ”—ο»Ώ)ο»Ώ

  • ο»Ώ[SKErrorCloudServicePermissionDenied](πŸ”—ο»Ώ)ο»Ώ

  • ο»Ώ[SKErrorOverlayInvalidConfiguration](πŸ”—ο»Ώ)ο»Ώ

  • ο»Ώ[SKErrorUnsupportedPlatform](πŸ”—ο»Ώ)ο»Ώ

  • ο»Ώ[SKErrorIneligibleForOffer](πŸ”—ο»Ώ)ο»Ώ

  • ο»Ώ[SKErrorClientInvalid](πŸ”—ο»Ώ)ο»Ώ

**Resolution:** Make sure the device and user are allowed to make in-app purchases. Try the following troubleshooting steps:

  • Make sure your device/emulator is completely updated.

  • Try running on device. Sometimes the emulator glitches out and it must be restarted. Overall, testing on device is more reliable.

  • Restart your device/emulator.

  • Make sure you're logged in with a Google account.

  • If you're running on an emulator, make sure it has Google Play installed.


ο»Ώ

# Restoring Errors

#### 🍎 πŸ€– `INVALID_RECEIPT`

**Problem:** Indicates the receipt is malformed or invalid.

**Resolution:** Receipt validation failed, no action required.


ο»Ώ

#### 🍎 `MISSING_RECEIPT_FILE`

**Problem:** Indicates there is no receipt file available on the device. This is more common in sandbox testing.

**Resolution:** Make sure you're signed into the device with a valid Apple account. For Sandbox testing, you may have to make a purchase to generate a receipt before attempting the operation. In Sandbox a receipt is generated when a user makes a purchase and is saved against the sandbox account. While in production a receipt is generated when a user downloads the app and is saved against the Apple account.


ο»Ώ

#### πŸ“¦ `ERROR_FINDING_RECEIPT_SKU`

**Problem:** Indicates there is no SKU available from the token.


ο»Ώ

#### πŸ“¦ `ERROR_FETCHING_RECEIPTS`

**Problem:** Indicates there was an error fetching receipts.


ο»Ώ

#### πŸ“¦ `ERROR_FETCHING_RECEIPT_INFO`

**Problem:** Indicates there was an error fetching information about the receipt.


ο»Ώ

#### πŸ“¦ `ERROR_OBSERVER_MODE_NOT_SUPPORTED`

**Problem:** Observer Mode is [not currently supported](πŸ”—ο»Ώ) for Amazon.

**Resolution:** Disable Observer Mode.

# Next Steps

  • You're set up to handle errors, time to start [making purchases in sandbox ο»Ώο»Ώ](πŸ”—ο»Ώ)ο»Ώ