# rpc.* and jsonrpc.* attributes: OpenTelemetry RPC conventions

> OpenTelemetry rpc.* and jsonrpc.* attributes: rpc.method, rpc.system.name, rpc.response.status_code, with a JSON-RPC span from a real Ethereum node call.

Source: https://hashspan.dev/learn/otel-attributes/rpc


From semantic-conventions v1.44.0 (e10a930). Synced 2026-10-18.

## Short answer

The `rpc.*` attributes describe one remote procedure call: `rpc.system.name` says which protocol (`grpc`, `jsonrpc` and others), `rpc.method` names the method and `rpc.response.status_code` holds the returned code. `jsonrpc.*` adds the JSON-RPC protocol version and request id. The core `rpc.*` attributes are Release candidate in v1.44.0.

## What do the rpc.* and jsonrpc.* attributes describe?

A call to an Ethereum node is JSON-RPC: `eth_sendRawTransaction`, `eth_getTransactionReceipt` and so on. Under the RPC conventions, each call is a CLIENT span named after `rpc.method`, with `rpc.system.name` set to `jsonrpc`.

If the method is unknown, `rpc.method` is `_OTHER` and the span is named after `rpc.system.name` instead. An error response puts its `error.code` in `rpc.response.status_code`, as a string.

## Which spans set them?

| Span name | Kind | Convention |
|---|---|---|
| `{rpc.method}` | CLIENT | rpc.call.client |
| `{rpc.method}` | SERVER | rpc.call.server |
| `{rpc.method}` | CLIENT | rpc.connect_rpc.call.client |
| `{rpc.method}` | SERVER | rpc.connect_rpc.call.server |
| `{rpc.method}` | CLIENT | rpc.grpc.call.client |
| `{rpc.method}` | SERVER | rpc.grpc.call.server |
| `{rpc.method}` | CLIENT | rpc.jsonrpc.call.client |
| `{rpc.method}` | SERVER | rpc.jsonrpc.call.server |
| `{rpc.method}` | CLIENT | rpc.dubbo.call.client |
| `{rpc.method}` | SERVER | rpc.dubbo.call.server |
| `{mcp.method.name}` | CLIENT | mcp.client |
| `{mcp.method.name}` | SERVER | mcp.server |

## What does a real span record?

Span `eth_fillTransaction` (CLIENT):

| Attribute | Value |
|---|---|
| `rpc.system.name` | `jsonrpc` |
| `rpc.method` | `eth_fillTransaction` |
| `jsonrpc.protocol.version` | `2.0` |
| `server.address` | `127.0.0.1` |
| `server.port` | `8545` |
| `blockchain.chain.id` | `31337` |

From a real run on 2026-10-18: `@hashspan/viem` 1.1.1 with viem 2.57.7 against a local Anvil node on port 8545. [The page this run is from](https://hashspan.dev/docs/viem-opentelemetry).

Its parent was `send 31337`, the transaction span. `blockchain.chain.id` is hashspan's own attribute, not part of the RPC conventions.

## Should a JSON-RPC client record rpc.method?

The JSON-RPC conventions say a general-purpose instrumentation SHOULD NOT set `rpc.method` by default, because a server can be sent any method name. They make it opt-in.

hashspan records it on every JSON-RPC span its viem transport creates, with the span named after the method. A name that is not a plain identifier (a letter, then up to 63 letters, digits or underscores) goes in as `_OTHER`, and the span is then named `jsonrpc`, its `rpc.system.name` (since hashspan 1.3).

## All 6 `rpc.*` attributes

### `rpc.method`

- Type: string
- Stability: Release candidate
- The fully-qualified logical name of the method from the RPC interface perspective.
- Examples: `com.example.ExampleService/exampleMethod`, `EchoService/Echo`, `_OTHER`
- Set on:
  - `{rpc.method}` CLIENT: rpc.call.client (conditionally required), rpc.connect_rpc.call.client (conditionally required), rpc.grpc.call.client (required), rpc.jsonrpc.call.client (opt-in), rpc.dubbo.call.client (required)
  - `{rpc.method}` SERVER: rpc.call.server (conditionally required), rpc.connect_rpc.call.server (conditionally required), rpc.grpc.call.server (conditionally required), rpc.jsonrpc.call.server (opt-in), rpc.dubbo.call.server (conditionally required)
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-method
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.method

### `rpc.method_original`

- Type: string
- Stability: Release candidate
- The original name of the method used by the client.
- Examples: `com.myservice.EchoService/catchAll`, `com.myservice.EchoService/unknownMethod`, `InvalidMethod`
- Set on:
  - `{rpc.method}` CLIENT: rpc.call.client (conditionally required), rpc.connect_rpc.call.client (conditionally required), rpc.grpc.call.client (conditionally required), rpc.jsonrpc.call.client (conditionally required), rpc.dubbo.call.client (conditionally required)
  - `{rpc.method}` SERVER: rpc.call.server (conditionally required), rpc.connect_rpc.call.server (conditionally required), rpc.grpc.call.server (conditionally required), rpc.jsonrpc.call.server (conditionally required), rpc.dubbo.call.server (conditionally required)
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-method-original
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.method_original

### `rpc.request.metadata.<key>`

- Type: string[]
- Stability: Development
- RPC request metadata, `<key>` being the normalized RPC metadata key (lowercase), the value being the metadata values.
- Examples: `["1.2.3.4","1.2.3.5"]`
- Set on:
  - `{rpc.method}` CLIENT: rpc.connect_rpc.call.client (opt-in), rpc.grpc.call.client (opt-in), rpc.dubbo.call.client (opt-in)
  - `{rpc.method}` SERVER: rpc.connect_rpc.call.server (opt-in), rpc.grpc.call.server (opt-in), rpc.dubbo.call.server (opt-in)
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-request-metadata
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.request.metadata

### `rpc.response.metadata.<key>`

- Type: string[]
- Stability: Development
- RPC response metadata, `<key>` being the normalized RPC metadata key (lowercase), the value being the metadata values.
- Examples: `["attribute_value"]`
- Set on:
  - `{rpc.method}` CLIENT: rpc.connect_rpc.call.client (opt-in), rpc.grpc.call.client (opt-in), rpc.dubbo.call.client (opt-in)
  - `{rpc.method}` SERVER: rpc.connect_rpc.call.server (opt-in), rpc.grpc.call.server (opt-in), rpc.dubbo.call.server (opt-in)
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-response-metadata
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.response.metadata

### `rpc.response.status_code`

- Type: string
- Stability: Release candidate
- Status code of the RPC returned by the RPC server or generated by the client
- Examples: `OK`, `DEADLINE_EXCEEDED`, `-32602`
- Set on:
  - `{rpc.method}` CLIENT: rpc.call.client (conditionally required), rpc.connect_rpc.call.client (conditionally required), rpc.grpc.call.client (required), rpc.jsonrpc.call.client (conditionally required), rpc.dubbo.call.client (required)
  - `{rpc.method}` SERVER: rpc.call.server (conditionally required), rpc.connect_rpc.call.server (conditionally required), rpc.grpc.call.server (required), rpc.jsonrpc.call.server (conditionally required), rpc.dubbo.call.server (required)
  - `{mcp.method.name}` CLIENT: mcp.client (conditionally required)
  - `{mcp.method.name}` SERVER: mcp.server (conditionally required)
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-response-status-code
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.response.status_code

### `rpc.system.name`

- Type: string
- Stability: Release candidate
- The Remote Procedure Call (RPC) system.
- Values: `grpc`, `dubbo`, `connectrpc`, `jsonrpc`
- Set on:
  - `{rpc.method}` CLIENT: rpc.call.client (required)
  - `{rpc.method}` SERVER: rpc.call.server (required)
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-system-name
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.system.name

## All 2 `jsonrpc.*` attributes

### `jsonrpc.protocol.version`

- Type: string
- Stability: Development
- Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response.
- Examples: `2.0`, `1.0`
- Set on:
  - `{rpc.method}` CLIENT: rpc.jsonrpc.call.client (conditionally required)
  - `{rpc.method}` SERVER: rpc.jsonrpc.call.server (conditionally required)
  - `{mcp.method.name}` CLIENT: mcp.client (recommended)
  - `{mcp.method.name}` SERVER: mcp.server (recommended)
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/jsonrpc/#jsonrpc-protocol-version
- Link: https://hashspan.dev/learn/otel-attributes/rpc#jsonrpc.protocol.version

### `jsonrpc.request.id`

- Type: string
- Stability: Development
- A string representation of the `id` property of the request and its corresponding response.
- Examples: `10`, `request-7`
- Set on:
  - `{rpc.method}` CLIENT: rpc.jsonrpc.call.client (recommended)
  - `{rpc.method}` SERVER: rpc.jsonrpc.call.server (recommended)
  - `{mcp.method.name}` CLIENT: mcp.client (conditionally required)
  - `{mcp.method.name}` SERVER: mcp.server (conditionally required)
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/jsonrpc/#jsonrpc-request-id
- Link: https://hashspan.dev/learn/otel-attributes/rpc#jsonrpc.request.id

## Which names were renamed or removed?

### `rpc.connect_rpc.error_code`

- Type: string
- Stability: Deprecated
- Renamed to `rpc.response.status_code`.
- Values: `cancelled`, `unknown`, `invalid_argument`, `deadline_exceeded`, `not_found`, `already_exists`, `permission_denied`, `resource_exhausted`, `failed_precondition`, `aborted`, `out_of_range`, `unimplemented`, `internal`, `unavailable`, `data_loss`, `unauthenticated`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-connect-rpc-error-code
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.connect_rpc.error_code

### `rpc.connect_rpc.request.metadata.<key>`

- Type: string[]
- Stability: Deprecated
- Renamed to `rpc.request.metadata.<key>`.
- Examples: `["1.2.3.4","1.2.3.5"]`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-connect-rpc-request-metadata
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.connect_rpc.request.metadata

### `rpc.connect_rpc.response.metadata.<key>`

- Type: string[]
- Stability: Deprecated
- Renamed to `rpc.response.metadata.<key>`.
- Examples: `["attribute_value"]`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-connect-rpc-response-metadata
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.connect_rpc.response.metadata

### `rpc.grpc.request.metadata.<key>`

- Type: string[]
- Stability: Deprecated
- Renamed to `rpc.request.metadata.<key>`.
- Examples: `["1.2.3.4","1.2.3.5"]`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-grpc-request-metadata
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.grpc.request.metadata

### `rpc.grpc.response.metadata.<key>`

- Type: string[]
- Stability: Deprecated
- Renamed to `rpc.response.metadata.<key>`.
- Examples: `["attribute_value"]`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-grpc-response-metadata
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.grpc.response.metadata

### `rpc.grpc.status_code`

- Type: string
- Stability: Deprecated
- Replaced by `rpc.response.status_code`.
- Values: `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`, `16`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-grpc-status-code
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.grpc.status_code

### `rpc.jsonrpc.error_code`

- Type: int
- Stability: Deprecated
- Replaced by `rpc.response.status_code`.
- Examples: `-32700`, `100`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-jsonrpc-error-code
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.jsonrpc.error_code

### `rpc.jsonrpc.error_message`

- Type: string
- Stability: Deprecated
- Use the span status description when reporting JSON-RPC spans.
- Examples: `Parse error`, `User already exists`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-jsonrpc-error-message
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.jsonrpc.error_message

### `rpc.jsonrpc.request_id`

- Type: string
- Stability: Deprecated
- Renamed to `jsonrpc.request.id`.
- Examples: `10`, `request-7`, ``
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-jsonrpc-request-id
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.jsonrpc.request_id

### `rpc.jsonrpc.version`

- Type: string
- Stability: Deprecated
- Renamed to `jsonrpc.protocol.version`.
- Examples: `2.0`, `1.0`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-jsonrpc-version
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.jsonrpc.version

### `rpc.message.compressed_size`

- Type: int
- Stability: Deprecated
- Deprecated, no replacement at this time.
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-message-compressed-size
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.message.compressed_size

### `rpc.message.id`

- Type: int
- Stability: Deprecated
- Deprecated, no replacement at this time.
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-message-id
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.message.id

### `rpc.message.type`

- Type: string
- Stability: Deprecated
- Deprecated, no replacement at this time.
- Values: `SENT`, `RECEIVED`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-message-type
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.message.type

### `rpc.message.uncompressed_size`

- Type: int
- Stability: Deprecated
- Deprecated, no replacement at this time.
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-message-uncompressed-size
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.message.uncompressed_size

### `rpc.service`

- Type: string
- Stability: Deprecated
- Value should be included in `rpc.method` which is expected to be a fully-qualified name.
- Examples: `myservice.EchoService`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-service
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.service

### `rpc.system`

- Type: string
- Stability: Deprecated
- Renamed to `rpc.system.name`.
- Values: `grpc`, `java_rmi`, `dotnet_wcf`, `apache_dubbo`, `connect_rpc`, `onc_rpc`, `jsonrpc`
- Official definition: https://opentelemetry.io/docs/specs/semconv/registry/attributes/rpc/#rpc-system
- Link: https://hashspan.dev/learn/otel-attributes/rpc#rpc.system

## FAQ

### What replaced rpc.system and rpc.service?

rpc.system was renamed to rpc.system.name. rpc.service is gone: its value is now part of a fully qualified rpc.method, such as com.example.ExampleService/exampleMethod.

### Where does a JSON-RPC error code go?

In rpc.response.status_code, as a string. The older rpc.jsonrpc.error_code attribute is deprecated, and rpc.jsonrpc.error_message gave way to the span status description.

## Read next

- [Trace viem with OpenTelemetry](https://hashspan.dev/docs/viem-opentelemetry)
- [Span kind: CLIENT, SERVER, INTERNAL](https://hashspan.dev/learn/otel-span-kind)
- [Span status and error.type](https://hashspan.dev/learn/otel-span-status)
- [Search every attribute](https://hashspan.dev/learn/otel-attributes.md)

Attribute names, types, stability and descriptions are from the OpenTelemetry semantic conventions, © OpenTelemetry Authors, Apache-2.0.
