---
title: "What does unknownError (code 0) mean in the purchases SDK?"
description: "unknownError (code 0) is the purchases SDK's catch-all for a failure it cannot classify. Read the underlying error, turn on debug logs and update the SDK."
url: https://revenuedot.app/docs/errors/sdk-unknown-error
---

# What does unknownError (code 0) mean in the purchases SDK?

The purchases SDK raises unknownError (code 0) when a failure matches none of its named errors.

## Quick facts

| | |
|---|---|
| Error | `ErrorCode.unknownError` (iOS), `PurchasesErrorCode.UnknownError` (Android), code 0 |
| Where | Purchases SDK (iOS, Android and the hybrid SDKs built on them) |
| What the vendor says | Unknown error. Check the underlying error for more details. |

## Cause

- A StoreKit or Play Billing error that the SDK has no mapping for. On iOS, `StoreKitError` cases that are newer than the SDK fall through to this error, and so does any other unmapped error.
- On Android, an exception that is not a network, security or signature failure becomes `UnknownError`, and so does any Play Billing response code outside the known list ([errors.kt](https://github.com/revenuedot/purchases-android/blob/revenuedot/main-patches/purchases/src/main/kotlin/com/revenuecat/purchases/google/errors.kt)).
- The backend answered with code 0, which the SDK reads as "we do not know what happened".

## Fix

1. Read the underlying error: on iOS `NSUnderlyingErrorKey` and `readable_error_code` in `userInfo`, on Android `error.underlyingErrorMessage`.
2. Turn on debug logs (`Purchases.logLevel = .debug`) and read the lines before the error.
3. Update the SDK. A StoreKit or Play error that is new to the operating system can be unmapped in an old release.
4. Do not unlock content and do not retry automatically; let the customer try again.

## Example

```swift
// The purchases SDK throws `ErrorCode` values; match the one you handle and let the rest fall through.
func handle(_ error: Error) {
    guard let code = error as? ErrorCode else {
        print("Not a purchases SDK error: \(error)")
        return
    }
    switch code {
    case .unknownError:
        print("Unknown failure: read the underlying error and the debug log")
    default:
        print("Other purchases error: \(code.description)")
    }
}
```

*Compile-checked: `npm run check:snippets` type-checks this snippet with `swiftc` together with the `ErrorCode.swift` file of the RevenueDot `purchases-ios` fork (checked 2026-10-03).*

## How the RevenueDot SDK reports it

RevenueDot answers server failures with a numeric `code`, so a server problem reaches the SDK as a backend error and not as `unknownError`. The full deep dive is on [revenuedot.app/errors/unknown-error](https://revenuedot.app/errors/unknown-error).

## Related

- [What does storeProblemError (code 2) mean in the purchases SDK?](https://revenuedot.app/docs/errors/sdk-store-problem-error.md)
- [What does StoreKitError.unknown mean?](https://revenuedot.app/docs/errors/storekit-error-unknown.md)
- [What does networkError (code 10) mean in the purchases SDK?](https://revenuedot.app/docs/errors/sdk-network-error.md)
- [What RevenueDot's API errors mean (server codes)](https://revenuedot.app/docs/api/errors.md)

## Source

- [RevenueDot purchases-ios: ErrorCode.swift (the iOS ErrorCode enum)](https://github.com/revenuedot/purchases-ios/blob/revenuedot/main-patches/Sources/Generated/ErrorCode.swift)
- [RevenueDot purchases-android: PurchasesErrorCode.kt (the Android enum)](https://github.com/revenuedot/purchases-android/blob/revenuedot/main-patches/purchases/src/main/kotlin/generated/com/revenuecat/purchases/PurchasesErrorCode.kt)
- [RevenueDot purchases-android: google/errors.kt (Play Billing mapping)](https://github.com/revenuedot/purchases-android/blob/revenuedot/main-patches/purchases/src/main/kotlin/com/revenuecat/purchases/google/errors.kt)

Checked: 2026-10-03
