---
title: "What does Play Billing ITEM_UNAVAILABLE (4) mean?"
description: "ITEM_UNAVAILABLE (4) means the product cannot be bought by this user. Check that it is active, the app is published and the product is sold in the user's country."
url: https://revenuedot.app/docs/errors/play-billing-item-unavailable
---

# What does Play Billing ITEM_UNAVAILABLE (4) mean?

Play Billing ITEM_UNAVAILABLE (4) means the product you asked to buy is not available for purchase for this user.

## Quick facts

| | |
|---|---|
| Error | `BillingClient.BillingResponseCode.ITEM_UNAVAILABLE` (4) |
| Where | Google Play Billing Library (`BillingResult.responseCode`) |
| What the vendor says | The requested product is not available for purchase. |

## Cause

- Google says a product must be active, its app must be published and its app must be available in the user's country to be sold.
- A product that is configured for another region than the user's returns this code. Google also says a change of country availability can take time to spread, so the code can appear after a correct change.
- During testing, a correct configuration can still return it for a while because product details take time to propagate across Google's servers.

## Fix

1. Refresh product details with `queryProductDetailsAsync` and only sell products that it returns.
2. Check the product's state, the app's publishing state and the product's country availability in Play Console.
3. If you changed availability recently, wait and try again later.
4. Hide the buy button for a product that did not come back from `queryProductDetailsAsync`.

## Example

```kotlin
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingResult

// ITEM_UNAVAILABLE is a catalog problem: log the product ID and hide the button instead of retrying.
fun onPurchaseResult(result: BillingResult, productId: String, hideProduct: (String) -> Unit) {
    if (result.responseCode == BillingClient.BillingResponseCode.ITEM_UNAVAILABLE) {
        println("ITEM_UNAVAILABLE for $productId: check it is active, the app is published and the country is allowed")
        hideProduct(productId)
    }
}
```

*Not compiled: this Kotlin snippet was not built here because the docs repo has no Kotlin or Android toolchain. Check it against your Play Billing Library or SDK version before you ship it.*

## How the RevenueDot SDK reports it

The RevenueDot `purchases-android` fork maps `ITEM_UNAVAILABLE` to `PurchasesErrorCode.ProductNotAvailableForPurchaseError` (code 5). In RevenueDot, the product's store identifier must equal the Play product ID. See [what productNotAvailableForPurchaseError means](https://revenuedot.app/docs/errors/sdk-product-not-available-for-purchase-error.md).

## Related

- [What does productNotAvailableForPurchaseError (code 5) mean in the purchases SDK?](https://revenuedot.app/docs/errors/sdk-product-not-available-for-purchase-error.md)
- [What does Product.PurchaseError.productUnavailable mean?](https://revenuedot.app/docs/errors/storekit-purchase-error-product-unavailable.md)
- [What does Play Billing DEVELOPER_ERROR (5) mean?](https://revenuedot.app/docs/errors/play-billing-developer-error.md)

## Source

- [Google: BillingResponseCode.ITEM_UNAVAILABLE](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode)
- [Google: Handle BillingResult response codes](https://developer.android.com/google/play/billing/errors)
- [RevenueDot purchases-android: google/errors.kt (how the SDK maps response codes)](https://github.com/revenuedot/purchases-android/blob/revenuedot/main-patches/purchases/src/main/kotlin/com/revenuecat/purchases/google/errors.kt)

Checked: 2026-10-03
