A2A Error Codes: JSON-RPC, gRPC, and HTTP Mapping
A2A defines nine errors of its own and maps each one onto the native error model of every binding. This page is the lookup: find the error you received, see what raised it, and see how it looks in JSON-RPC, gRPC, and HTTP+JSON. The narrative version is in Core Protocol Specification and Protocol Bindings in Detail . Checked against A2A v1.0.1.
Every error, in every binding, MUST convey a machine-readable code and a human-readable message, and can add a list of detail objects, each with an @type key. The specification asks implementations to use the well-known google.rpc types such as ErrorInfo and BadRequest where they apply.
The nine A2A errors
| Error | JSON-RPC | gRPC | HTTP | ErrorInfo.reason | Raised when |
|---|---|---|---|---|---|
TaskNotFoundError | -32001 | NOT_FOUND | 404 | TASK_NOT_FOUND | The task ID does not match an existing or accessible task: invalid, expired, or purged |
TaskNotCancelableError | -32002 | FAILED_PRECONDITION | 400 | TASK_NOT_CANCELABLE | Cancel was requested for a task that is not in a cancelable state, such as one already in a terminal state |
PushNotificationNotSupportedError | -32003 | FAILED_PRECONDITION | 400 | PUSH_NOTIFICATION_NOT_SUPPORTED | Push notifications were used but capabilities.pushNotifications is false |
UnsupportedOperationError | -32004 | FAILED_PRECONDITION | 400 | UNSUPPORTED_OPERATION | The operation, or part of it, is not supported by this agent |
ContentTypeNotSupportedError | -32005 | INVALID_ARGUMENT | 400 | CONTENT_TYPE_NOT_SUPPORTED | A media type in the request parts, or implied for an artifact, is not supported by the agent or the skill |
InvalidAgentResponseError | -32006 | INTERNAL | 500 | INVALID_AGENT_RESPONSE | The agent returned a response that does not conform to the specification for the method |
ExtendedAgentCardNotConfiguredError | -32007 | FAILED_PRECONDITION | 400 | EXTENDED_AGENT_CARD_NOT_CONFIGURED | No extended Agent Card is configured although the operation requires one |
ExtensionSupportRequiredError | -32008 | FAILED_PRECONDITION | 400 | EXTENSION_SUPPORT_REQUIRED | The server needs an extension marked required: true in the card and the client did not declare support for it |
VersionNotSupportedError | -32009 | FAILED_PRECONDITION | 400 | VERSION_NOT_SUPPORTED | The A2A-Version service parameter names a version the agent does not support |
The specification states the reason rule as: the error name in UPPER_SNAKE_CASE without the Error suffix, with domain always set to a2a-protocol.org. It spells out TASK_NOT_FOUND and TASK_NOT_CANCELABLE; the other values in the column follow from the same rule.
Telling errors with the same status apart
Seven of the nine errors share HTTP 400, and six share gRPC FAILED_PRECONDITION. The status alone does not identify the error. That is why the specification requires a google.rpc.ErrorInfo detail on every A2A-specific error in the gRPC and HTTP+JSON bindings: read reason there. In JSON-RPC the numeric code is already unique.
Which operation raises which error
The specification lists these errors per operation. Errors that are not tied to one operation are listed under the table.
| Operation | Errors the specification lists |
|---|---|
SendMessage | ContentTypeNotSupportedError, UnsupportedOperationError (the task is in a terminal state), TaskNotFoundError |
SendStreamingMessage | UnsupportedOperationError (streaming not supported, or the task is in a terminal state), ContentTypeNotSupportedError, TaskNotFoundError |
GetTask | TaskNotFoundError |
ListTasks | None specific to the operation |
CancelTask | TaskNotCancelableError, TaskNotFoundError |
SubscribeToTask | UnsupportedOperationError (streaming not supported, or the task is in a terminal state), TaskNotFoundError |
| Create, Get, List, and Delete push notification config | PushNotificationNotSupportedError, TaskNotFoundError (the task, or for Get the configuration, does not exist) |
GetExtendedAgentCard | UnsupportedOperationError (the agent does not support extended cards), ExtendedAgentCardNotConfiguredError (support is declared but no card is configured) |
Not tied to one operation:
VersionNotSupportedError: any request whoseA2A-Versionthe agent does not support.ExtensionSupportRequiredError: a required extension that the client did not declare.InvalidAgentResponseError: the specification gives no per-operation trigger.
Cancel is idempotent, but a repeated cancel request MAY return TaskNotFoundError once the canceled task has been purged.
Beyond the nine
Failures that are not specific to A2A use each binding’s native codes. The specification groups them in five categories:
| Category | HTTP | gRPC | JSON-RPC |
|---|---|---|---|
| Authentication | 401 | UNAUTHENTICATED | custom error |
| Authorization | 403 | PERMISSION_DENIED | custom error |
| Validation | 400 | INVALID_ARGUMENT | -32602 |
| Resource | 404 | NOT_FOUND | custom (A2A-specific) error |
| System | 500 or 503 | INTERNAL or UNAVAILABLE | -32603 |
Servers MUST NOT reveal whether a resource exists to a client that is not authorized to access it, and SHOULD NOT distinguish “does not exist” from “not authorized”.
JSON-RPC also has five standard codes. A2A-specific codes live in the range -32001 to -32099.
| Code | Name | Standard message |
|---|---|---|
-32700 | JSONParseError | “Invalid JSON payload” |
-32600 | InvalidRequestError | “Request payload validation error” |
-32601 | MethodNotFoundError | “Method not found” |
-32602 | InvalidParamsError | “Invalid parameters” |
-32603 | InternalError | “Internal error” |
The same error in each binding
The three elements map differently in each binding:
| Element | JSON-RPC | gRPC | HTTP+JSON |
|---|---|---|---|
| Code | error.code (numeric) | status.code | HTTP status and error.code |
| Message | error.message | status.message | error.message |
| Details | error.data (an array) | status.details | error.details (an array) |
JSON-RPC calls the detail list data; the other two call it details. These are the specification’s own examples of a task-not-found error.
JSON-RPC
{
"jsonrpc": "2.0",
"id": 2,
"error": {
"code": -32001,
"message": "Task not found",
"data": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "TASK_NOT_FOUND",
"domain": "a2a-protocol.org",
"metadata": {
"taskId": "nonexistent-task-id",
"timestamp": "2025-11-09T10:30:00.000Z"
}
}
]
}
}gRPC
status {
code: NOT_FOUND
message: "Task with ID 'task-123' not found"
details: [
{
type: "type.googleapis.com/google.rpc.ErrorInfo"
reason: "TASK_NOT_FOUND"
domain: "a2a-protocol.org"
metadata: {
task_id: "task-123"
timestamp: "2025-11-09T10:30:00Z"
}
}
]
}HTTP+JSON
HTTP/1.1 404 Not Found
Content-Type: application/a2a+json
{
"error": {
"code": 404,
"status": "NOT_FOUND",
"message": "The specified task ID does not exist or is not accessible",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "TASK_NOT_FOUND",
"domain": "a2a-protocol.org",
"metadata": {
"taskId": "task-123",
"timestamp": "2025-11-09T10:30:00.000Z"
}
}
]
}
}Validation failures use google.rpc.BadRequest in the same slot. The specification’s example is a request whose message.parts is empty, reported as a field violation with the description “At least one part is required”.
Related pages
- Protocol Bindings in Detail : service parameters, methods, and streaming for each binding.
- AgentSkill
: the media types that
ContentTypeNotSupportedErroris checked against. - Task
: the terminal states behind
TaskNotCancelableErrorandUnsupportedOperationError.