---
title: Error codes
nav: Error codes
description: Every error code the application surfaces, what actually caused it, and what to do about it.
group: reference
order: 2
status: shipped
updated: 2026-09-21
---

Codes are stable identifiers. Messages attached to them may be Google's own text passed through verbatim, which is why the code is usually more informative than the sentence beside it.

## Store and provider

### `GOOGLE_PERMISSION_DENIED`

Google returned `403` on an Android Publisher call. Surfaced to the application as `STORE_PERMISSION_ERROR`.

The message is Google's, and its most common form — _"The caller does not have permission"_ — names no endpoint and no permission. What it means depends on which call failed:

- **Catalogue listing succeeded, price conversion failed.** A Play Console permission gap. The service account can read app information but is not granted the monetization permission. Fix under **Users and permissions**, wait a few minutes, re-sync.
- **Everything failed.** The service account was never granted access to this app, or the developer account does not own it.

This does not indicate a credential problem. See [Store baselines](/guidelines/store-baseline).

### `GOOGLE_INVALID_CREDENTIALS`

Google returned `401`, or the private key could not be parsed. The service-account key is wrong, malformed, or revoked. Re-submit the key on the connection.

### `GOOGLE_PACKAGE_NOT_FOUND`

Google returned `404`. The package name is wrong, or the developer account does not own that application.

### `GOOGLE_RATE_LIMITED`

Google returned `429`. Retried automatically with backoff; if it reaches you, the retries were exhausted. Re-sync later.

### `GOOGLE_API_ERROR`

Any other Google failure. `5xx` responses are retried before surfacing.

### `PRODUCT_SYNC_ERROR`

Every application in a sync failed to import. Carries the underlying failures as context. Returned as `502`.

## Catalogue sync

### `CATALOG_SYNC_FAILED`

One application's import failed, or — at sync level — all of them did.

### `CATALOG_SYNC_PARTIAL`

Some applications imported and some did not. The successful ones are saved; the failures are recorded per application with their own reason.

## Baseline failures

Baseline failures are **not** error codes. They are reported per plan as part of a successful import, because a conversion that fails must not fail an otherwise valid read-only import.

Two forms:

- _"This plan has no US price, and Google converts from the US price."_ — a legitimate catalogue shape.
- Google's own error text, passed through — usually the permission gap above.

## Credential vault

### `STORE_PERMISSION_ERROR`

The vault returned `403`. Either Google refused the operation, or the operation itself is not on the vault's allowlist.

The two are distinguishable by message: the vault's own refusal reads _"Google operation is not allowed."_ Anything else came from Google.

### `STORE_CONNECTION_ERROR`

The vault could not be reached, returned an unstructured response, or failed for a reason other than permission.

### `VAULT_MAINTENANCE_FORBIDDEN`

A maintenance operation was attempted without valid maintenance authorization. Maintenance is authorized separately from ordinary credential use, so a compromised application cannot rotate or export keys.

## Application

### `NOT_FOUND`

The record does not exist, or belongs to another workspace. The two are deliberately indistinguishable: a workspace-scoped query treats another workspace's row as a miss rather than a permission error, so existence is never leaked.

### `INTERNAL_ERROR`

An unclassified failure. If a store operation produces this rather than a specific code, the classification is missing — worth reporting.
