---
title: "What does VerificationError.invalidSignature mean in StoreKit 2?"
description: "VerificationResult.VerificationError.invalidSignature means a signed StoreKit 2 value failed its signature check. Do not unlock content from an unverified transaction."
url: https://revenuedot.app/docs/errors/storekit-verification-error-invalid-signature
---

# What does VerificationError.invalidSignature mean in StoreKit 2?

VerificationResult.VerificationError.invalidSignature means the signature of a signed StoreKit 2 value did not match its header and payload.

## Quick facts

| | |
|---|---|
| Error | `VerificationResult.VerificationError.invalidSignature` |
| Where | StoreKit 2, Swift (`VerificationResult`) |
| 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 signature did not match the header and payload. |

## Cause

- StoreKit 2 returns transactions, renewal information and the app transaction wrapped in a `VerificationResult`. It checks them automatically, and a value that fails is `.unverified`, with the reason as a `VerificationError` ([VerificationResult](https://developer.apple.com/documentation/storekit/verificationresult)).
- `invalidSignature` is one of six reasons Apple lists, next to `invalidCertificateChain`, `invalidDeviceVerification`, `invalidEncoding`, `missingRequiredProperties` and `revokedCertificate`.
- It means the signed text was altered or does not belong to the signature. Apple gives no further detail on the case page.

## Fix

1. Treat an `.unverified` result as untrusted. Do not unlock content from it.
2. Log the `VerificationError` and the transaction ID, then check the same transaction on your server with the App Store Server Library, as Apple suggests for the highest security.
3. Check that the test environment is set up correctly if you only see it in testing.
4. Do not call `finish()` on an unverified transaction until you have decided what to do with it.

## Example

```swift
import StoreKit

// Only a verified transaction may unlock content. Log the reason for an unverified one.
func handle(_ result: VerificationResult<Transaction>) {
    switch result {
    case .verified(let transaction):
        print("Unlock \(transaction.productID)")
    case .unverified(let transaction, let error):
        if case .invalidSignature = error {
            print("Signature check failed for \(transaction.productID); do not unlock")
        } else {
            print("Verification 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 turns an unverified transaction into `ErrorCode.storeProblemError` (code 2) with the `VerificationError` as the underlying error, and it does not unlock the purchase. RevenueDot's server also verifies the signed transaction on its side.

## Related

- [What does invalidReceiptError (code 8) mean in the purchases SDK?](https://revenuedot.app/docs/errors/sdk-invalid-receipt-error.md)
- [What does Product.PurchaseError.invalidOfferSignature mean?](https://revenuedot.app/docs/errors/storekit-purchase-error-invalid-offer-signature.md)
- [What does storeProblemError (code 2) mean in the purchases SDK?](https://revenuedot.app/docs/errors/sdk-store-problem-error.md)

## Source

- [Apple: VerificationResult.VerificationError.invalidSignature](https://developer.apple.com/documentation/storekit/verificationresult/verificationerror/invalidsignature)
- [Apple: VerificationResult](https://developer.apple.com/documentation/storekit/verificationresult)
- [RevenueDot purchases-ios: StoreKit2TransactionListener.swift](https://github.com/revenuedot/purchases-ios/blob/revenuedot/main-patches/Sources/Purchasing/StoreKit2/StoreKit2TransactionListener.swift)

Checked: 2026-10-03
