UCP Error Codes Explained: Standard Codes and Structural Organization

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 – Defines the canonical error identifiers (e.g., not_found, out_of_stock) as extensible string enumerations.
  2. message_error.json – Wraps the error code with severity metadata, human-readable content, optional path pointers, and content type declarations.
  3. 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:

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:

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:

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 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/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) to HTTP 401.

MCP Discovery Failure

Profile unreachability in JSON-RPC transport produces:

{
  "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.

Embedded Checkout Validation Error

For missing required fields in embedded contexts:

{
  "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, including the continue_url for graceful fallback flows.

Summary

  • UCP error codes follow a three-layer JSON Schema: error_code.json (identifiers), message_error.json (severity and content), and 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) 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) 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, while Cart errors appear in docs/specification/cart.md. All capability codes reuse the 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →