grpcio-status provides the Python binding for the google.rpc.Status protobuf, enabling rich (structured) error details to be packed into gRPC trailing metadata and unpacked on the client side. It sits on top of grpcio and protobuf, exposing two primary helpers — rpc_status.to_status() and rpc_status.from_call() — both marked EXPERIMENTAL in the source. The package is versioned in strict lockstep with grpcio (current: 1.78.0) and is released on the same cadence, typically every 4–6 weeks.
Install & Compatibility
Where this runs
tested against v1.81.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.950 runs
installs and imports cleanly · install 0.0s · import 0.548s · 41.5MB
glibcpy 3.10–3.950 runs
installs and imports cleanly · install 3.1s · import 0.290s · 39MB
39MB installed
● package 39MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
rpc_status
✓ from grpc_status import rpc_status
✗ import grpc_status.rpc_status
The installable package is grpcio-status but the importable top-level package is grpc_status (underscore, not hyphen). Direct module import without 'from' raises ImportError.
rpc_status.from_call
✓ from grpc_status import rpc_status; status = rpc_status.from_call(rpc_error)
Pass the grpc.RpcError exception object directly — it implements grpc.Call. Returns None if the server did not pack a google.rpc.Status into trailing metadata; always guard against None.
rpc_status.to_status
✓ from grpc_status import rpc_status; context.abort_with_status(rpc_status.to_status(rich_status))
✗ context.set_code(...); context.set_details(...)
Use abort_with_status(rpc_status.to_status(...)) on the server side to send rich status atomically. Using set_code/set_details separately does NOT embed the google.rpc.Status proto in trailing metadata, so clients will receive None from from_call().
status_pb2.Status
✓ from google.rpc import status_pb2
google.rpc is supplied by googleapis-common-protos, not by grpcio-status itself. Install googleapis-common-protos separately.
error_details_pb2
✓ from google.rpc import error_details_pb2
Structured detail types (BadRequest, RetryInfo, QuotaFailure, DebugInfo, etc.) live in googleapis-common-protos, not in grpcio-status.
Server aborts with a rich google.rpc.Status; client unpacks the structured error detail.
# pip install grpcio grpcio-status googleapis-common-protos
import grpc
from grpc_status import rpc_status
from google.rpc import status_pb2, code_pb2, error_details_pb2
from google.protobuf import any_pb2
# --- SERVER SIDE (inside a servicer method) ---
def MyRpc(request, context):
# Build a structured error detail
detail = any_pb2.Any()
detail.Pack(
error_details_pb2.BadRequest(
field_violations=[
error_details_pb2.BadRequest.FieldViolation(
field="name",
description="must not be empty",
)
]
)
)
rich_status = status_pb2.Status(
code=code_pb2.INVALID_ARGUMENT,
message="Invalid request",
details=[detail],
)
# abort_with_status atomically sets code + message + trailing metadata
context.abort_with_status(rpc_status.to_status(rich_status))
# --- CLIENT SIDE ---
def call_rpc(stub):
try:
stub.MyRpc(request=object()) # placeholder
except grpc.RpcError as rpc_error:
# from_call returns None when no rich status was packed
status = rpc_status.from_call(rpc_error)
if status is None:
print("No rich status; plain code:", rpc_error.code())
return
print("gRPC status code:", rpc_error.code())
for detail in status.details:
if detail.Is(error_details_pb2.BadRequest.DESCRIPTOR):
info = error_details_pb2.BadRequest()
detail.Unpack(info)
for v in info.field_violations:
print(f"Field '{v.field}': {v.description}")
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'grpc_status'
This error occurs when the Python interpreter cannot find the `grpc_status` module, typically because the `grpcio-status` package has not been installed or is not accessible in the current Python environment.
fixEnsure the `grpcio-status` package is installed using pip: `pip install grpcio-status`. If using virtual environments or tools like PySpark, verify that the package is installed in the correct environment being used by the application.
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. grpcio-status X.Y.Z requires protobuf<A.B.C,>=D.E.F, but you have protobuf G.H.I which is incompatible.
This conflict arises because `grpcio-status` has specific version requirements for the `protobuf` library, and another installed package (or a different version of `protobuf` itself) has conflicting requirements, leading to an incompatible `protobuf` version in the environment.
fixTry to resolve the dependency conflict by either downgrading or upgrading your `protobuf` installation to a version compatible with `grpcio-status` and other dependent packages. A common strategy is to uninstall `protobuf` and `grpcio-status`, then reinstall `grpcio-status` which should pull a compatible `protobuf` version, or explicitly install a `protobuf` version known to work with your `grpcio-status` version.
AttributeError: 'RpcError' object has no attribute 'code'
This error occurs when attempting to access the `code` attribute directly on a `grpc.RpcError` object as a property, rather than calling it as a method.
fixAccess the status code by calling the `code()` method on the `RpcError` object: `error.code()` instead of `error.code`.
Audit
Dependencies
grpciorequiredCore gRPC runtime — must match grpcio-status version exactly to avoid subtle ABI mismatches.
protobufrequiredRequired for google.rpc.status_pb2 and Any packing/unpacking of error details. grpcio-status>=1.51 requires protobuf>=4.21.6.
googleapis-common-protosoptionalProvides google.rpc.code_pb2 and google.rpc.error_details_pb2 (RetryInfo, BadRequest, DebugInfo, etc.) used in rich error detail payloads.