What does Product.PurchaseError.productUnavailable mean?

Product.PurchaseError.productUnavailable means the App Store reports that this product is not available to buy.

Quick facts#

Error Product.PurchaseError.productUnavailable
Where StoreKit 2, Swift (Product.purchase(options:))
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 product is not available.

Cause#

  • The App Store has the product but will not sell it to this customer right now. Apple's page for the case gives no further reason.
  • Apple notes that if an identifier is invalid or the App Store cannot find it, Product.products(for:) leaves it out of the result instead of throwing (products(for:)). A product you hold but cannot buy is a different state from one that never loaded.
  • Products are sold per region, and Apple tells developers to keep their own list of identifiers and the storefronts where they are available (Storefront).

Fix#

  1. Check the product in App Store Connect: it must exist, have complete metadata and be available in the customer's region.
  2. Compare the identifier in your code character by character with the one in App Store Connect.
  3. Reload products and compare the IDs you asked for with the IDs that came back, to see which one is missing.
  4. Hide or disable the buy button for the product until it loads, and do not retry the same call in a loop.

Example#

Swift
import StoreKit

// Compare what you asked for with what came back, so a missing product is a log line instead of a silent dead button.
func buy(id: String) async {
    do {
        guard let product = try await Product.products(for: [id]).first else {
            print("The App Store returned no product for \(id); check the identifier and availability")
            return
        }
        _ = try await product.purchase()
    } catch Product.PurchaseError.productUnavailable {
        print("\(id) exists but cannot be bought right now")
    } catch {
        print("Purchase failed: \(error)")
    }
}

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 maps Product.PurchaseError.productUnavailable to ErrorCode.productNotAvailableForPurchaseError (code 5). In RevenueDot, make sure the product's store identifier equals the App Store identifier. See what productNotAvailableForPurchaseError means.

Source#

Checked: 2026-10-03

Edit this page on GitHub ↗ View as Markdown Last updated