SKError codes and how to handle them
Updated: October 9, 2023
13 min read
In our series of articles, my team and I are talking about in-app purchases implementation for iOS. And this is the fifth article in the series. Follow the links to read the previous ones:
- iOS in-app purchases, part 1: configuration and adding to the project.
- iOS in-app purchases, part 2: initialization and purchases processing.
- iOS in-app purchases, part 3: testing purchases in XCode.
- iOS in-app purchases, part 4: server-side receipt validation.
- iOS in-app purchases: the list of SKError codes and how to handle them.
In this post, I will address the SKErrors: what problems they imply and what to do about them. For each error, we will work out three aspects: why it occurs, how to handle them, and what message to display in the error notification.
SKError.Code.unknown, code=0
What it means. An error occurred for an unknown reason.
How to fix it. No action is needed from the developers’ side. This error also comes on the request when trying to get products when using the iOS 14 and above simulator. In this case, to get a product, use the StoreKit local testing or a real device/emulator with the iOS version below iOS 14.
What message to display. Sorry, the purchase is unavailable for an unknown reason. Please try again later.
SKError.Code.clientInvalid, code=1
What it means. The user cannot make a purchase. For example, a child tries to buy something when the parental control function on the device is on.
How to fix it. No action is needed from the developers’ side.
What message to display. The purchase cannot be completed. Please, change your account or device.
SKError.Code.paymentCancelled, code=2
What it means. The user got to the payment screen, but changed his mind about making a purchase and clicked “cancel”.
How to fix it. From a technical point of view, no error occurred and, in this case, nothing needs to be done. From a marketing point of view, you can continue working with such a user, for example, offer them a discount.
What message to display. You have two options here. The easiest one is not to show anything. However, you can also try winning a user back with a message like this: “You have canceled your purchase. Are you interested in trying a subscription at a discounted price?”
SKError.Code.paymentInvalid, code=3
What it means. For some reason, the payment failed: the card had expired or there were not enough funds for this purchase.
How to fix it. No action is needed from the developers’ side.
What message to display. Your purchase was declined. Please, check the payment details and make sure there are enough funds in your account.
SKError.Code.paymentNotAllowed, code=4
What it means. This card probably has some purchase restrictions available: limits are set or the online shopping function is unavailable.
How to fix it. No action is needed from the developers’ side.
What message to display. The purchase is not available for the selected payment method. Please, make sure your payment method allows you to make online purchases.
SKError.Code.storeProductNotAvailable, code=5
What it means. The user is trying to buy a product that is not available for the region in which this store is used.
How to fix it. The developer needs to check products for their availability in the user’s store and region. For this, you can use SKStorefront.
What message to display. This product is not available in your region. Please, change the store and try again.
SKError.Code.cloudServicePermissionDenied, code=6
What it means. The user didn’t give access to the information of their Cloud service.
How to fix it. No action is needed from the developers’ side.
What message to display. To be honest, I have never met such an error. Actually, you can just write that the purchase was declined.
SKError.Code.cloudServiceNetworkConnectionFailed, code=7
What it means. The device was not connected to the Internet when making a purchase.
How to fix it. No action is needed from the developers’ side.
What message to display. The purchase cannot be completed because your device is not connected to the Internet. Please, try again later with a stable internet connection.
2024 subscription benchmarks and insights
Get your free copy of our latest subscription report to stay ahead in 2024.
SKError.Code.cloudServiceRevoked, code=8
What it means. This device doesn’t have access to the StoreKit payment service. Commonly, this error occurs in Sandbox.
How to fix it. Create a new Sandbox user or just try repeating the operation.
What message to display. Sorry, an error has occurred.
SKError.Code.privacyAcknowledgementRequired, code=9
What it means. The user didn’t accept the terms of use in the AppStore. As it’s said in the documentation, “the user has not yet acknowledged Apple’s privacy policy for Apple Music”. But it looks like an error, because there is no reason to mention Apple Music here.
How to fix it. No action is needed from the developers’ side.
What message to display. The purchase cannot be completed because you have not accepted the terms of use of the AppStore. Please, confirm your consent in the settings and then return to the purchase.
SKError.Code.unauthorizedRequestData, code=10
What it means. Your app ID doesn’t contain the required entitlement for using StoreKit.
How to fix it. You need to finish the setup process of in-app purchases for your app.
What message to display. An error has occurred. Please, try again later.
SKError.Code.invalidOfferIdentifier, code=11
What it means. The user is trying to buy a product with an incorrect promotional offer.
How to fix it. No action is needed from the developers’ side.
What message to display. The promotional offer is invalid or expired.
SKError.Code.invalidSignature, code=12
What it means. The signature for the promotional offer for the StoreKit request was generated incorrectly.
How to fix it. Check how the signature is generated and fix the errors. If you use Adapty, download the Subscription Key.
What message to display. Sorry, an error has occurred when applying the promo code. Please, try again later.
SKError.Code.missingOfferParams, code=13
What it means. Parameters of the promotional offer are formed incorrectly.
How to fix it. Check and correct the parameters of your promotional offer.
What message to display. Sorry, an error has occurred when applying the promo offer. Please, try again later.
SKError.Code.invalidOfferPrice, code=14
What it means. The user is trying to buy a product with an irrelevant price. Probably, the price displayed in the AppStore is no longer valid.
How to fix it. Set the updated price for this offer in the AppStore.
What message to display. Sorry, your purchase cannot be completed. Please, try again later.
SKError.Code.overlayCancelled, code=15
What it means. The user has cancelled a purchase or other transaction within the in-app purchase overlay. When a user attempts to make an in-app purchase, the StoreKit framework presents an overlay that allows the user to complete the transaction. If the user cancels the purchase at any point during this process, the framework returns the SKError.Code.overlayCancelled
error code to the app.
How to fix it. You can handle this error code by dismissing the in-app purchase overlay and notifying the user that the transaction has been cancelled. You should also ensure that any data related to the cancelled transaction is properly handled and cleaned up in your app.
What message to display. An error has occurred. Please, try again later.
SKError.Code.overlayInvalidConfiguration, code=16
What it means. There is a problem with the configuration of the in-app purchase overlay. This error can occur if there is missing or incorrect information in the configuration of your in-app purchases, such as missing product identifiers or incorrect payment configuration settings.
How to fix it. Check the configuration of your in-app purchases and ensure that all required fields are properly configured. This may involve checking your product identifiers, verifying your payment configuration settings, and ensuring that your app is properly configured to handle in-app purchases.
What message to display. An error has occurred. Please, try again later.
SKError.Code.overlayTimeout, code=17
What it means. The in-app purchase overlay has timed out while waiting for a response from the user or the App Store.
How to fix it. Ensure that your app is properly configured to handle in-app purchases and that your code is properly handling the purchase flow. You may also want to consider optimizing the performance of your app to reduce the likelihood of timeouts or delays during in-app purchases.
What message to display. An error has occurred. Please, try again later.
SKError.Code.ineligibleForOffer, code=18
What it means. The user is not eligible for a particular offer or promotion associated with an in-app purchase. This error can occur if the user does not meet the eligibility requirements for the offer, such as geographic location, age, or other criteria set by the app developer or the App Store.
How to fix it. Review the eligibility criteria for the offer and ensure that they are properly documented and communicated to users. You may also want to consider providing alternative offers or promotions for users who are not eligible for the original offer.
What message to display. An error has occurred. Please, try again later.
SKError.Code.unsupportedPlatform, code=19
What it means. The app is running on an unsupported platform or device. This error can occur if the app is attempting to make an in-app purchase on a device or platform that is not supported by the StoreKit framework or the App Store. For example, some in-app purchases may be restricted to certain iOS versions or devices, and attempting to make a purchase on an unsupported platform could result in such an error.
How to fix it. Review the requirements and limitations of your in-app purchases and ensure that they are compatible with the platforms and devices that your app supports.
What message to display. An error has occurred. Please, try again later.
SKError.Code.overlayPresentedInBackgroundScene, code=20
What it means. The in-app purchase overlay was presented in a background scene instead of the active scene.
How to fix it. Ensure that your app is properly managing its scenes and that the in-app purchase overlay is presented in the active scene. You may also want to consider optimizing the performance of your app to reduce the likelihood of background scenes becoming active during the in-app purchase process.
What message to display. An error has occurred. Please, try again later.
Conclusion
Correct error handling improves user experience and can return at least some of those users who could not pay for the subscription immediately for some reason. These are the most common mistakes when implementing purchases in an iOS app:
- SKError.Code.unknown, an unknown error;
- SKError.Code.paymentCancelled, when the user cancels the purchase;
- SKError.Code.paymentInvalid, when the payment can’t be processed.
Actually, error handling and purchase implementation are cumbersome processes. So I would recommend trying Adapty SDK for iOS, which makes implementing in-app purchases easier and provides other benefits, such as subscription analytics, cohort analysis, A/B tests for paywalls, and server-side receipt validation.