# UCP Error Codes Explained: Standard Codes and Structural Organization

> Understand UCP error codes with this guide to standard codes and structural organization. Learn how UCP standardizes error handling across multiple transports.

- Repository: [Universal Commerce Protocol (UCP)/ucp](https://github.com/Universal-Commerce-Protocol/ucp)
- Tags: api-reference
- Published: 2026-04-26

---

**UCP (Universal Commerce Protocol) defines a single, extensible error-code model built from three layered JSON Schema components that standardize error handling across REST, JSON-RPC (MCP), and Embedded transports.**

The Universal Commerce Protocol repository (`Universal-Commerce-Protocol/ucp`) implements a unified error system designed for cross-platform commerce applications. Understanding the standard **UCP error codes** and their hierarchical organization is essential for debugging integration failures, handling transport-specific mappings, and implementing graceful error recovery in checkout flows.

## Three-Layer JSON Schema Architecture

UCP organizes errors through a strict three-layer schema hierarchy defined in the `source/schemas/shopping/types/` directory:

1. **[`error_code.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/error_code.json)** – Defines the canonical error identifiers (e.g., `not_found`, `out_of_stock`) as extensible string enumerations.
2. **[`message_error.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/message_error.json)** – Wraps the error code with severity metadata, human-readable content, optional path pointers, and content type declarations.
3. **[`error_response.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/error_response.json)** – The top-level envelope that forces `ucp.status` to `"error"` and bundles multiple messages (errors, warnings, or info) with optional continuation URLs.

This layered approach ensures that **capability-specific errors** (Checkout, Cart, Catalog, etc.) reuse the same structural foundation while remaining extensible for domain-specific failures.

## Structural Hierarchy of Error Responses

All transport implementations follow this consistent nesting structure:

```text
ErrorResponse
│
├─ ucp (status = "error")
└─ messages[]
     ├─ MessageError   [uses error_code.json + severity]
     ├─ MessageWarning
     └─ MessageInfo

```

The **`severity`** field drives UI and automation behavior through four distinct levels:

- **recoverable** – The platform can retry automatically without user intervention.
- **requires_buyer_input** – Immediate attention required (e.g., invalid phone number).
- **requires_buyer_review** – User must review warnings before proceeding.
- **unrecoverable** – Terminal failure requiring transaction termination.

## Core Error Code Categories

UCP groups standard error codes into three core categories defined in the specification documentation.

### Negotiation Errors

Negotiation errors occur during the discovery phase before business logic processing begins, typically relating to profile fetching or capability mismatch. These codes appear in [`docs/specification/overview.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/overview.md):

| Code | Description | REST HTTP | MCP JSON-RPC |
|------|-------------|-----------|--------------|
| `invalid_profile_url` | Profile URL malformed, missing, or unresolvable | 400 | -32001 |
| `profile_unreachable` | URL resolved but fetch failed (timeout, non-2xx) | 424 | -32001 |
| `profile_malformed` | Fetched content invalid JSON or schema violation | 422 | -32001 |
| `version_unsupported` | Platform protocol version not supported | 422 | -32001 |
| `capabilities_incompatible` | No compatible capabilities intersection found | 200* | — |

*Note: `capabilities_incompatible` returns HTTP 200 in the result payload rather than as an error status.*

### Signature Errors

Signature errors represent HTTP Message Signature validation failures defined in [`docs/specification/signatures.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/signatures.md):

| Code | Description | REST HTTP | MCP JSON-RPC |
|------|-------------|-----------|--------------|
| `signature_missing` | Required signature header absent | 401 | -32000 |
| `signature_invalid` | Signature verification failed | 401 | -32000 |
| `key_not_found` | Key ID not found in signer's `signing_keys` | 401 | -32000 |
| `digest_mismatch` | Body digest doesn't match `Content-Digest` header | 400 | -32600 |
| `algorithm_unsupported` | Signature algorithm not supported | 400 | -32600 |

### Protocol Errors

Protocol errors map standard HTTP status codes to JSON-RPC equivalents for transport abstraction:

| HTTP Code | Description | MCP `error.code` |
|-----------|-------------|------------------|
| `401` | Authentication required or credentials invalid | -32000 |
| `403` | Authenticated but insufficient permissions | -32000 |
| `409` | Idempotency key reused with different payload | -32000 |
| `429` | Too many requests (rate limiting) | -32000 |
| `500` | Unexpected server error | -32603 |
| `503` | Service temporarily unavailable | -32000 |

## Capability-Specific Error Codes

Each UCP capability (Checkout, Cart, Catalog, Discount, Embedded Checkout) registers domain-specific codes that extend the base model. These reuse the `MessageError` structure from [`source/schemas/shopping/types/message_error.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/types/message_error.json) while defining contextual meanings:

- **Checkout**: `out_of_stock`, `invalid_phone`, `eligibility_invalid`, `field_required`, `allergens`
- **Cart**: `out_of_stock`, `not_found`
- **Catalog**: `not_found`, `delayed_fulfillment`
- **Discount**: `discount_code_expired`
- **Embedded Checkout**: `security_error`, `missing`, `invalid_address`, `abort_error`, `window_open_rejected_error`

As implemented in `Universal-Commerce-Protocol/ucp`, these capability-specific codes integrate seamlessly with the core severity system and transport bindings.

## Transport-Specific Bindings

UCP error codes adapt to three transport mechanisms while maintaining semantic consistency:

### REST Transport

Errors return as HTTP status codes with JSON bodies containing `{ "code": "<error_code>", "content": "Human message" }`. The `error_code` string appears alongside standard HTTP semantics (401, 403, 429, etc.).

### MCP (JSON-RPC) Transport

Errors appear within the JSON-RPC `"error"` object:
- `code`: JSON-RPC error number (e.g., -32000, -32600)
- `message`: Generic phrase
- `data.code`: The canonical UCP error code string

### Embedded Transport

Direct JSON-RPC responses over peer-to-peer channels use the same mapping as MCP but omit HTTP-specific status codes, relying entirely on the structured `ErrorResponse` envelope.

## Code Examples

### REST Signature Error Response

When signature verification fails, the REST transport returns:

```http
HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
  "code": "signature_invalid",
  "content": "Request signature verification failed for key kid=platform-2026"
}

```

This maps the `signature_invalid` code (defined in [`docs/specification/signatures.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/signatures.md)) to HTTP 401.

### MCP Discovery Failure

Profile unreachability in JSON-RPC transport produces:

```json
{
  "jsonrpc": "2.0",
  "id": 42,
  "error": {
    "code": -32001,
    "message": "Discovery failure",
    "data": {
      "code": "profile_unreachable",
      "content": "Unable to fetch agent profile: connection timeout",
      "retry_after": 30
    }
  }
}

```

The `profile_unreachable` code uses the standard **Negotiation Error** mapping to JSON-RPC code -32001, as specified in [`docs/specification/overview.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/overview.md).

### Embedded Checkout Validation Error

For missing required fields in embedded contexts:

```json
{
  "ucp": {
    "version": "2026-01-23",
    "status": "error"
  },
  "messages": [
    {
      "type": "error",
      "code": "missing",
      "content": "The required field `shipping_address` is missing.",
      "severity": "requires_buyer_input",
      "content_type": "plain"
    }
  ],
  "continue_url": "https://merchant.example.com/checkout/123"
}

```

This example demonstrates the full `ErrorResponse` envelope from [`source/schemas/shopping/types/error_response.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/types/error_response.json), including the `continue_url` for graceful fallback flows.

## Summary

- **UCP error codes** follow a three-layer JSON Schema: [`error_code.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/error_code.json) (identifiers), [`message_error.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/message_error.json) (severity and content), and [`error_response.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/error_response.json) (envelope).
- **Core categories** include Negotiation errors (profile issues), Signature errors (cryptographic validation), and Protocol errors (HTTP status equivalents).
- **Severity levels** (recoverable, requires_buyer_input, requires_buyer_review, unrecoverable) determine automation versus human intervention requirements.
- **Transport mappings** translate codes consistently: REST uses HTTP status codes, MCP uses JSON-RPC error numbers (-32000, -32600), and Embedded uses direct JSON-RPC without HTTP wrapping.
- **Capability-specific codes** (Checkout, Cart, Catalog, etc.) extend the base model while maintaining structural compatibility.

## Frequently Asked Questions

### What is the difference between MessageError and ErrorResponse in UCP?

`MessageError` (defined in [`source/schemas/shopping/types/message_error.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/types/message_error.json)) represents a single error occurrence containing the code, human-readable content, severity, and optional path. `ErrorResponse` (defined in [`source/schemas/shopping/types/error_response.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/types/error_response.json)) is the top-level envelope that contains the `ucp` metadata object and an array of messages. Every error response contains at least one MessageError within its messages array, but may also include warnings or informational messages.

### How do UCP error codes map between REST and MCP transports?

UCP maintains semantic consistency through transport-specific bindings. REST errors expose both HTTP status codes (401, 403, 429) and JSON body codes (`signature_invalid`, `out_of_stock`). MCP wraps these in JSON-RPC error objects using numeric codes (-32000 for authentication/permission issues, -32001 for negotiation failures, -32600 for invalid parameters, -32603 for internal errors) while placing the canonical UCP code string inside `data.code`.

### Where are capability-specific error codes like out_of_stock defined?

Domain-specific codes such as `out_of_stock`, `invalid_phone`, and `discount_code_expired` are defined within individual capability specification documents under `docs/specification/`. For example, Checkout-specific errors appear in [`docs/specification/checkout.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/checkout.md), while Cart errors appear in [`docs/specification/cart.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/cart.md). All capability codes reuse the [`error_code.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/error_code.json) base type and `MessageError` structure for consistency.

### What does the severity field control in UCP error handling?

The **severity** field in [`message_error.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/message_error.json) drives UI behavior and automation decisions. `recoverable` errors allow automatic retry without user interruption. `requires_buyer_input` demands immediate user correction (e.g., fixing an invalid address). `requires_buyer_review` presents warnings that must be acknowledged before proceeding. `unrecoverable` terminates the transaction and requires abandonment or restart. This system enables platforms to distinguish between transient network failures and fatal business logic violations.