---
title: "What does Product.PurchaseError.missingOfferParameters mean?"
description: "Product.PurchaseError.missingOfferParameters means the offer parameters are missing from a purchase. Send the offer ID, key ID, nonce, signature and timestamp, or the signed JWS."
url: https://revenuedot.app/docs/errors/storekit-purchase-error-missing-offer-parameters
---

# What does Product.PurchaseError.missingOfferParameters mean?

Product.PurchaseError.missingOfferParameters means the purchase named an offer but did not carry all the parameters the App Store needs to apply it.

## Quick facts

| | |
|---|---|
| Error | `Product.PurchaseError.missingOfferParameters` |
| 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 offer parameters are missing. |

## Cause

- Apple's case page gives only that one line. It lists no causes.
- A promotional offer needs several values: the offer ID, and either the key ID, nonce, signature and timestamp from your server, or a compact JWS signed on your server. The `promotionalOffer(offerID:keyID:nonce:signature:timestamp:)` option takes the first group.
- From iOS 26 the signature-and-nonce option is deprecated in the StoreKit interface in favor of `promotionalOffer(_:compactJWS:)`, so apps that mix the two styles can leave a part out.

## Fix

1. Build the offer option from one server response that contains every value, and pass nothing partial.
2. Move to the JWS option (`promotionalOffer(_:compactJWS:)`) when your minimum iOS version allows it. It carries the signed offer as one string.
3. Check that your server returns the key ID, the nonce, the timestamp and the signature, and that the app does not drop one while decoding.
4. Request a fresh signature for each attempt. A signature works for one purchase request only.

## Example

```swift
import StoreKit

// Pass every parameter from one server response, so none is missing.
struct SignedOffer {
    let offerID: String
    let keyID: String
    let nonce: UUID
    let signature: Data
    let timestamp: Int
}

func buy(_ product: Product, offer: SignedOffer) async {
    let option = Product.PurchaseOption.promotionalOffer(offerID: offer.offerID, keyID: offer.keyID, nonce: offer.nonce, signature: offer.signature, timestamp: offer.timestamp)
    do {
        _ = try await product.purchase(options: [option])
    } catch Product.PurchaseError.missingOfferParameters {
        print("An offer parameter is missing; request a complete signed offer from the server")
    } 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.missingOfferParameters` to `ErrorCode.invalidPromotionalOfferError` (code 34). The SDK assembles the offer parameters itself when you use its promotional offer API, so you see this mostly when you build the option by hand.

## Related

- [What does Product.PurchaseError.invalidOfferSignature mean?](https://revenuedot.app/docs/errors/storekit-purchase-error-invalid-offer-signature.md)
- [What does Product.PurchaseError.invalidOfferPrice mean?](https://revenuedot.app/docs/errors/storekit-purchase-error-invalid-offer-price.md)
- [What does Product.PurchaseError.invalidOfferIdentifier mean?](https://revenuedot.app/docs/errors/storekit-purchase-error-invalid-offer-identifier.md)

## Source

- [Apple: Product.PurchaseError.missingOfferParameters](https://developer.apple.com/documentation/storekit/product/purchaseerror/missingofferparameters)
- [Apple: promotionalOffer purchase option](https://developer.apple.com/documentation/storekit/product/purchaseoption/promotionaloffer%28offerid:keyid:nonce:signature:timestamp:%29)
- [Apple: Generating a signature for promotional offers](https://developer.apple.com/documentation/storekit/generating-a-signature-for-promotional-offers)
- [RevenueDot purchases-ios: StoreKitError+Extensions.swift (how the SDK maps StoreKit 2 errors)](https://github.com/revenuedot/purchases-ios/blob/revenuedot/main-patches/Sources/Error%20Handling/StoreKitError%2BExtensions.swift)

Checked: 2026-10-03
