---
title: Checkout MCP errors
description: >-
  Learn how Checkout MCP returns protocol errors, business outcomes, warnings,
  and checkout messages.
source_url:
  html: 'https://shopify.dev/docs/agents/carts-and-checkout/checkout-errors'
  md: 'https://shopify.dev/docs/agents/carts-and-checkout/checkout-errors.md'
---

# Checkout MCP errors

Checkout MCP distinguishes between protocol errors and business outcomes.

* **Protocol errors** prevent Shopify from processing the request. They're returned as a top-level JSON-RPC `error`.
* **Business outcomes** are returned after Shopify processes the request. They're returned as a JSON-RPC `result` with `structuredContent` and a `messages` array.

***

## Protocol errors

Protocol errors are returned when a request can't be authenticated, authorized, negotiated, parsed, or routed to the requested tool. The response doesn't include a checkout resource.

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "Unauthorized"
  }
}
```

Discovery and capability-negotiation failures use the JSON-RPC `error` envelope. Shopify returns `-32001` for UCP discovery failures and can include a more specific code in `error.data.code`, such as `profile_unreachable` or `version_unsupported`.

Retry protocol errors only when the failure is temporary, such as rate limiting or service unavailability. When Shopify returns an HTTP `Retry-After` header, wait for that duration before retrying. For lifecycle-changing requests, include an `idempotency-key` before retrying.

***

## Business outcomes

Business outcomes are returned as a successful JSON-RPC `result`. The request was processed, but Shopify might return either a Checkout with messages or an `ErrorResponse`.

### Checkout returned with messages

Use the checkout's `status` and `messages` together to decide whether to update the checkout, complete it, or hand off to the buyer.

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "status": "success",
        "capabilities": {
          "dev.ucp.shopping.checkout": [
            {
              "version": "2026-08-25",
              "spec": "https://ucp.dev/2026-08-25/specification/shopping/checkout/"
            }
          ]
        }
      },
      "id": "gid://shopify/Checkout/abc123?key=xyz789",
      "status": "requires_escalation",
      "currency": "USD",
      "line_items": [
        {
          "id": "gid://shopify/CartLine/li_1?cart=abc123",
          "item": {
            "id": "gid://shopify/ProductVariant/12345678901",
            "title": "Organic Cotton Sweater",
            "price": 8900
          },
          "quantity": 1,
          "totals": [
            { "type": "subtotal", "amount": 8900 },
            { "type": "total", "amount": 8900 }
          ]
        }
      ],
      "totals": [
        { "type": "subtotal", "amount": 8900 },
        { "type": "total", "amount": 8900 }
      ],
      "links": [
        { "type": "privacy_policy", "url": "https://shop.example.com/policies/privacy" },
        { "type": "terms_of_service", "url": "https://shop.example.com/policies/terms" }
      ],
      "messages": [
        {
          "type": "error",
          "code": "redirect_to_checkout_required",
          "severity": "requires_buyer_input",
          "content": "The buyer must continue in checkout."
        },
        {
          "type": "error",
          "code": "delivery_phone_number_required",
          "severity": "recoverable",
          "content": "Shipping address is missing a phone number",
          "path": "$.fulfillment.methods[0].destinations[0].phone_number"
        }
      ],
      "continue_url": "https://shop.example.com/checkouts/c/abc123?key=xyz789"
    }
  }
}
```

### Checkout not created

An `ErrorResponse` is returned when Shopify processes the request but can't create or return a checkout. For example, this can happen when the requested merchandise can't be added to a checkout. Inspect `ucp.status`, `messages`, and `continue_url` instead of checkout fields.

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "status": "error"
      },
      "messages": [
        {
          "type": "error",
          "code": "item_unavailable",
          "severity": "unrecoverable",
          "content": "Item cannot be purchased",
          "path": "$.line_items[0].item.id"
        }
      ],
      "continue_url": "https://shop.example.com/"
    }
  }
}
```

Always inspect `result.structuredContent.ucp.status` and `result.structuredContent.messages`. When a Checkout response is returned, also inspect `result.structuredContent.status`. Some warnings can be returned alongside a checkout that can continue, while some errors require either an `update_checkout` call or buyer handoff through `continue_url`.

***

## Message fields

Checkout messages use the following fields:

| Field | Description |
| - | - |
| `type` | Message type. Usually `error`, `warning`, or `info`. |
| `code` | Machine-readable outcome code. Use the code with `severity`, `status`, and `continue_url` before branching in your agent flow. |
| `severity` | The recommended recovery path. See [Severity values](#severity-values). |
| `content` | Human-readable message that can help explain the issue. |
| `content_type` | Message format. Usually `plain`; can be `markdown`. |
| `path` | JSONPath-style pointer to the affected request or checkout field, when available. |

***

## Severity values

| Severity | Meaning | Recommended action |
| - | - | - |
| `recoverable` | The agent can fix the checkout through API updates. | Prompt for the missing or corrected value, then call `update_checkout`. |
| `requires_buyer_input` | The buyer must provide information that isn't available through the API flow. | Hand off through `continue_url`. |
| `requires_buyer_review` | The buyer must review or approve something in the merchant checkout. | Hand off through `continue_url`. |
| `unrecoverable` | The checkout can't continue from the current state. | Start a new cart or checkout, or show the buyer an alternative. |

When messages include `requires_buyer_input` or `requires_buyer_review`, the checkout status can be `requires_escalation`. Use `continue_url` to send the buyer to the merchant checkout.

***

## Error code behavior

This is not an exhaustive list. For most integrations, branch first on `severity`, checkout `status`, and the presence of `continue_url`. Branch on `code` only for codes your integration explicitly handles.

### Common handling codes

| Code | Meaning | Recommended action |
| - | - | - |
| `out_of_stock` | The requested item can't be fulfilled in the requested quantity. | Refresh product data, adjust quantity, or suggest alternatives. |
| `item_unavailable` | The requested item can't be purchased in the current checkout context. | Remove or replace the item, then create or update the checkout. |
| `address_undeliverable` | Shopify can't find a delivery option for the destination. | Ask the buyer for a different address or remove items that can't ship. |
| `payment_failed` | The submitted payment method or payment configuration can't be used. | Ask for a different payment path or hand off through `continue_url`. |
| `redirect_to_checkout_required` | The buyer must complete an action in the merchant checkout. | Hand off through `continue_url`. |

For `item_unavailable`, Shopify returns generic localized content when possible, such as `Item cannot be purchased`. Other codes can include content from checkout validation. Treat `content` as explanatory text, not as a stable identifier.

### Tool and submission codes

Some codes describe the tool call or checkout submission state instead of checkout validation.

| Code | Meaning | Recommended action |
| - | - | - |
| `invalid_input` | A supplied value is malformed, empty, or uses the wrong resource type. | Correct the request before retrying. |
| `invalid_checkout_id` | The value isn't a valid Shopify Checkout GID. | Correct the checkout ID before retrying. |
| `checkout_not_found` | The checkout ID is validly formatted, but the checkout doesn't exist or is no longer available. | Start a new checkout. |
| `checkout_completion_throttled` | Checkout submission is throttled. | Retry after the returned `poll_after` timestamp. |
| `checkout_completion_timeout` | Shopify timed out while waiting for checkout completion. | Retry with the same idempotency key. |
| `checkout_completion_ineligible` | The checkout can't be completed through the API. | Hand off through `continue_url`. |

***

## Warnings

Warnings are non-fatal messages. A warning can be returned by itself, or with errors in the same `messages` array. For example, Shopify can return a discount warning while still returning a checkout resource and `continue_url`.

```json
{
  "type": "warning",
  "code": "discount_code_invalid",
  "severity": "recoverable",
  "content": "Enter a valid discount code",
  "path": "$.discounts.codes[0]"
}
```

Warning codes can vary by checkout configuration, discounts, inventory, and merchant capabilities. Don't rely on `isError` alone. Inspect the full `messages` array, message severities, `continue_url`, and the checkout `status` when a Checkout response is returned before deciding whether to call `update_checkout`, hand off to the buyer, or continue without the warning condition.

***
