What does StoreKitError.notAvailableInStorefront mean?
StoreKitError.notAvailableInStorefront means StoreKit 2 refused a function because the device's App Store storefront does not support it.
Quick facts#
| Error | StoreKitError.notAvailableInStorefront |
| Where | StoreKit 2, Swift (StoreKitError) |
| Available since | iOS 15.0, iPadOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0 |
| What the vendor says | The function is not available on devices configured for this storefront. |
Cause#
- The device's App Store country or region (its storefront) is one where the requested function is not offered. Apple documents the case in one line and does not publish a list of the calls or storefronts that trigger it.
- In-app products you create in App Store Connect are sold per region, and Apple says you keep your own list of product identifiers and the storefronts where you want them available (Storefront).
- In the sandbox, changing the App Store Country or Region of a Sandbox Apple Account changes the storefront your app sees, so a tester can hit this error after a region change (Storefront).
Fix#
- Read the storefront with
Storefront.currentand log itscountryCodenext to the error, so you know which region failed. - Check in App Store Connect that the product's availability includes that region, and check the app's own availability too.
- Do not retry in a loop. The same call fails the same way until the storefront or the availability changes. Hide the product or show a short "not available in your region" message instead.
- To reproduce it, change the region of a Sandbox Apple Account and run the same call again.
Example#
Swift
import StoreKit
// Load products, and explain a storefront problem instead of retrying: the same call keeps failing in that region.
func loadProducts(ids: [String]) async -> [Product] {
do {
return try await Product.products(for: ids)
} catch StoreKitError.notAvailableInStorefront {
// Log the region so support can tell a storefront problem from a network problem.
let region = await Storefront.current?.countryCode ?? "unknown"
print("StoreKit says this function is not available in storefront \(region)")
return []
} catch {
print("Could not load products: \(error)")
return []
}
}Compile-checked: npm run check:snippets type-checks this snippet with swiftc against the Apple SDK (macOS target, checked 2026-10-03).
How the RevenueDot SDK reports it#
The RevenueDot purchases-ios fork converts StoreKitError.notAvailableInStorefront into ErrorCode.productNotAvailableForPurchaseError (code 5), the same mapping as the RevenueCat SDK it forks. On Android, Play Billing's ITEM_UNAVAILABLE maps to the same code. Read what productNotAvailableForPurchaseError means for the SDK side.
Related#
- What does productNotAvailableForPurchaseError (code 5) mean in the purchases SDK?
- What does Product.PurchaseError.productUnavailable mean?
- What does Play Billing ITEM_UNAVAILABLE (4) mean?
Source#
- Apple: StoreKitError.notAvailableInStorefront
- Apple: Storefront
- RevenueDot purchases-ios: StoreKitError+Extensions.swift (how the SDK maps StoreKit 2 errors)
Checked: 2026-10-03