{"id":508,"library":"grpcio-health-checking","title":"gRPC Health Checking","description":"grpcio-health-checking provides a standard Health Checking Service for gRPC servers, implementing the `grpc.health.v1` service API. It allows gRPC clients, load balancers, and orchestration systems to verify the availability and health status of gRPC services. The current version is 1.78.0, with new releases typically occurring every 2-3 months.","status":"active","version":"1.78.0","language":"python","source_language":"en","source_url":"https://github.com/grpc/grpc/tree/master/src/python/grpcio_health_checking","tags":["grpc","health check","microservices","monitoring"],"install":[{"cmd":"pip install grpcio-health-checking grpcio","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Core gRPC library required for server and client functionalities.","package":"grpcio"}],"imports":[{"symbol":"health","correct":"from grpc_health.v1 import health"},{"symbol":"health_pb2","correct":"from grpc_health.v1 import health_pb2"},{"symbol":"health_pb2_grpc","correct":"from grpc_health.v1 import health_pb2_grpc"},{"symbol":"HealthServicer","correct":"from grpc_health.v1.health import HealthServicer"}],"quickstart":{"code":"import grpc\nimport time\nfrom concurrent import futures\nfrom grpc_health.v1 import health_pb2, health_pb2_grpc\nfrom grpc_health.v1.health import HealthServicer\n\n# --- Server Side ---\nclass MyServiceServicer(object):\n    def SayHello(self, request, context):\n        return health_pb2.HealthCheckResponse()\n\ndef serve():\n    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))\n\n    # Add your own gRPC service here if you have one\n    # my_service_pb2_grpc.add_MyServiceServicer_to_server(MyServiceServicer(), server)\n\n    health_servicer = HealthServicer()\n    health_pb2_grpc.add_HealthServicer_to_server(health_servicer, server)\n\n    # Set initial status for the overall server (empty string) and a specific service\n    health_servicer.set('', health_pb2.HealthCheckResponse.ServingStatus.SERVING)\n    health_servicer.set('MyService', health_pb2.HealthCheckResponse.ServingStatus.SERVING)\n\n    server.add_insecure_port('[::]:50051')\n    server.start()\n    print('Server started on port 50051...')\n    \n    try:\n        while True:\n            time.sleep(86400) # One day in seconds\n    except KeyboardInterrupt:\n        health_servicer.enter_graceful_shutdown() # Important for client notification\n        server.stop(0)\n\n# --- Client Side ---\ndef check_health():\n    with grpc.insecure_channel('localhost:50051') as channel:\n        stub = health_pb2_grpc.HealthStub(channel)\n        try:\n            # Check overall server health\n            response_overall = stub.Check(health_pb2.HealthCheckRequest(service=''))\n            print(f\"Overall Server Health: {health_pb2.HealthCheckResponse.ServingStatus.Name(response_overall.status)}\")\n\n            # Check specific service health\n            response_my_service = stub.Check(health_pb2.HealthCheckRequest(service='MyService'))\n            print(f\"'MyService' Health: {health_pb2.HealthCheckResponse.ServingStatus.Name(response_my_service.status)}\")\n\n        except grpc.RpcError as e:\n            if e.code() == grpc.StatusCode.UNIMPLEMENTED:\n                print(\"Health checking is not implemented by the server.\")\n            else:\n                print(f\"Error checking health: {e.details}\")\n\nif __name__ == '__main__':\n    import threading\n\n    server_thread = threading.Thread(target=serve)\n    server_thread.daemon = True # Allow main program to exit even if thread is running\n    server_thread.start()\n\n    time.sleep(1) # Give server time to start\n    check_health()\n","lang":"python","description":"This quickstart demonstrates both server-side implementation and client-side health checking. The server initializes a `HealthServicer`, adds it to the gRPC server, and sets the health status for the overall server (empty string) and a hypothetical 'MyService'. The client then uses a `HealthStub` to query these statuses. It includes handling for graceful shutdown notification and `UNIMPLEMENTED` status."},"warnings":[{"fix":"Ensure that `grpcio` and `grpcio-health-checking` are installed in a clean environment and that their `protobuf` dependencies are compatible. Consider using a virtual environment and `pip install --upgrade grpcio grpcio-health-checking` to ensure consistent versions. Refer to Protobuf's cross-version runtime guarantee documentation.","message":"Mismatched Protobuf Gencode/Runtime versions can lead to `google.protobuf.runtime_version.VersionError`. This occurs when `grpcio` and `grpcio-health-checking` are compiled or installed with incompatible versions of the `protobuf` package.","severity":"breaking","affected_versions":"All versions, particularly noted with `grpcio==1.72.0` and `protobuf==6.31.0-rc1`."},{"fix":"Implement a shutdown hook (e.g., a `KeyboardInterrupt` handler) to call `health_servicer.enter_graceful_shutdown()` before stopping your gRPC server.","message":"It is crucial to notify the health check service when your gRPC server is shutting down gracefully. Failing to call `HealthServicer.enter_graceful_shutdown()` means connected clients will not be informed that the service is no longer serving, potentially leading to continued (and failed) health checks.","severity":"gotcha","affected_versions":"All versions."},{"fix":"Clients should include logic to catch `grpc.StatusCode.UNIMPLEMENTED` errors and gracefully handle the absence of health checking functionality, typically by ceasing further health check attempts for that service.","message":"When a gRPC client performs a health check, if the `Check` or `Watch` RPC call fails with an `UNIMPLEMENTED` status, the client should assume that health checking is not supported by the server for that service and should disable further health checks for it.","severity":"gotcha","affected_versions":"All versions."}],"env_vars":null,"last_verified":"2026-05-12T14:29:32.043Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the package using pip: `pip install grpcio-health-checking`.","cause":"The `grpcio-health-checking` package is not installed in your Python environment or there's a typo in the import statement (e.g., using a hyphen instead of an underscore in the package name during import, though the package itself is installed via `pip install grpcio-health-checking`).","error":"ModuleNotFoundError: No module named 'grpc-health-checking'"},{"fix":"Ensure compatible versions of `grpcio` and `protobuf` are installed. Explicitly install or downgrade `protobuf` to a stable version known to work with your `grpcio` version. For example, `pip install grpcio==<version> protobuf==<compatible_version>` or try `pip install --upgrade grpcio protobuf` to get the latest compatible stable versions. Often, reinstalling `grpcio` alone can resolve it by pulling the correct `protobuf` dependency: `pip install --upgrade grpcio grpcio-health-checking`.","cause":"This error occurs when the `grpcio-health-checking` package (or `grpcio` itself) is used with an incompatible version of the `protobuf` library, often due to `grpcio` installing a pre-release or slightly mismatched version of `protobuf`.","error":"google.protobuf.runtime_version.VersionError: Detected mismatched Protobuf Gencode/Runtime version suffixes when loading grpc_health/v1/health.proto: gencode X.Y.Z runtime A.B.C."},{"fix":"Upgrade your `protobuf` library to a version that includes the `runtime_version` module. A common fix is `pip install --upgrade protobuf`.","cause":"This `ImportError` typically indicates that `grpcio-health-checking` expects a `protobuf` version that includes the `runtime_version` module (introduced in protobuf 5.27.0 or later), but an older version of `protobuf` is installed.","error":"ImportError: cannot import name 'runtime_version' from 'google.protobuf' (.../google/protobuf/__init__.py)"},{"fix":"Ensure that you have correctly added the `HealthServicer` to your gRPC server. In Python, this involves creating a `health.HealthServicer()` instance and registering it with your server: `health_pb2_grpc.add_HealthServicer_to_server(health.HealthServicer(), server)`.","cause":"This gRPC status error means that a client is trying to call the `Check` method of the `grpc.health.v1.Health` service, but the gRPC server does not have the `HealthServicer` registered or correctly implemented.","error":"UNIMPLEMENTED: Method not found: grpc.health.v1.Health/Check"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":8.3,"disk_size":"40.0M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.13,"mem_mb":7.4,"disk_size":"38M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.69,"mem_mb":9.3,"disk_size":"42.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":8.4,"disk_size":"40M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.84,"mem_mb":9.4,"disk_size":"34.3M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.46,"mem_mb":8.7,"disk_size":"32M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.81,"mem_mb":9.6,"disk_size":"34.0M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.46,"mem_mb":9.2,"disk_size":"32M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":8.4,"disk_size":"39.5M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":7.5,"disk_size":"37M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}