From dd79efb99b5b63b3354300cf449ec3dae315ec42 Mon Sep 17 00:00:00 2001 From: alliasgher Date: Tue, 14 Apr 2026 11:41:24 +0500 Subject: [PATCH 1/2] grpc_client: check SERVING status in Ping GRPCClient.Ping only checked whether the gRPC health-check RPC returned an error. A plugin that is reachable but in a non-SERVING state (e.g. NOT_SERVING) would cause Ping to return nil even though the plugin is not ready to serve requests. Propagate the response status: if it is not HealthCheckResponse_SERVING, return an error that includes the service name and the status value. Fixes #341 Signed-off-by: alliasgher --- grpc_client.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/grpc_client.go b/grpc_client.go index 41fedc36..7c985cf5 100644 --- a/grpc_client.go +++ b/grpc_client.go @@ -126,9 +126,16 @@ func (c *GRPCClient) Dispense(name string) (interface{}, error) { // ClientProtocol impl. func (c *GRPCClient) Ping() error { client := grpc_health_v1.NewHealthClient(c.Conn) - _, err := client.Check(context.Background(), &grpc_health_v1.HealthCheckRequest{ + resp, err := client.Check(context.Background(), &grpc_health_v1.HealthCheckRequest{ Service: GRPCServiceName, }) + if err != nil { + return err + } + + if resp.Status != grpc_health_v1.HealthCheckResponse_SERVING { + return fmt.Errorf("plugin %q health check returned non-SERVING status: %s", GRPCServiceName, resp.Status) + } - return err + return nil } From da445f6d3abac2cd290577ddf60d16c83946cd69 Mon Sep 17 00:00:00 2001 From: alliasgher Date: Tue, 14 Apr 2026 11:45:38 +0500 Subject: [PATCH 2/2] grpc_stdio, plugin_test: migrate from deprecated github.com/golang/protobuf/ptypes/empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the deprecated github.com/golang/protobuf/ptypes/empty import with the canonical google.golang.org/protobuf/types/known/emptypb. The underlying wire format is identical — the two packages are wire-compatible aliases — so this is a no-op at runtime but removes the dependency on the legacy module. Fixes #338 Signed-off-by: alliasgher --- go.mod | 2 +- grpc_stdio.go | 6 +++--- plugin_test.go | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index edd9bf22..55dc416f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/hashicorp/go-plugin go 1.24 require ( - github.com/golang/protobuf v1.5.4 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/yamux v0.1.2 github.com/jhump/protoreflect v1.17.0 @@ -15,6 +14,7 @@ require ( require ( github.com/bufbuild/protocompile v0.14.1 // indirect github.com/fatih/color v1.13.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.17 // indirect golang.org/x/net v0.38.0 // indirect diff --git a/grpc_stdio.go b/grpc_stdio.go index 737f2f7a..9096b890 100644 --- a/grpc_stdio.go +++ b/grpc_stdio.go @@ -9,7 +9,7 @@ import ( "context" "io" - empty "github.com/golang/protobuf/ptypes/empty" + "google.golang.org/protobuf/types/known/emptypb" hclog "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin/internal/plugin" "google.golang.org/grpc" @@ -49,7 +49,7 @@ func newGRPCStdioServer(log hclog.Logger, srcOut, srcErr io.Reader) *grpcStdioSe // StreamStdio streams our stdout/err as the response. func (s *grpcStdioServer) StreamStdio( - _ *empty.Empty, + _ *emptypb.Empty, srv plugin.GRPCStdio_StreamStdioServer, ) error { // Share the same data value between runs. Sending this over the wire @@ -101,7 +101,7 @@ func newGRPCStdioClient( client := plugin.NewGRPCStdioClient(conn) // Connect immediately to the endpoint - stdioClient, err := client.StreamStdio(ctx, &empty.Empty{}) + stdioClient, err := client.StreamStdio(ctx, &emptypb.Empty{}) // If we get an Unavailable or Unimplemented error, this means that the plugin isn't // updated and linking to the latest version of go-plugin that supports diff --git a/plugin_test.go b/plugin_test.go index 0f5a42d1..02623d2a 100644 --- a/plugin_test.go +++ b/plugin_test.go @@ -17,7 +17,7 @@ import ( "testing" "time" - "github.com/golang/protobuf/ptypes/empty" + "google.golang.org/protobuf/types/known/emptypb" "github.com/hashicorp/go-hclog" grpctest "github.com/hashicorp/go-plugin/test/grpc" "google.golang.org/grpc" @@ -285,14 +285,14 @@ func (s *testGRPCServer) Bidirectional(ctx context.Context, req *grpctest.Bidire func (s *testGRPCServer) PrintStdio( ctx context.Context, req *grpctest.PrintStdioRequest, -) (*empty.Empty, error) { +) (*emptypb.Empty, error) { s.Impl.PrintStdio(req.Stdout, req.Stderr) - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (s *testGRPCServer) Panic(ctx context.Context, req *grpctest.PanicRequest) (*empty.Empty, error) { +func (s *testGRPCServer) Panic(ctx context.Context, req *grpctest.PanicRequest) (*emptypb.Empty, error) { err := s.Impl.Panic(req.Message) - return &empty.Empty{}, err + return &emptypb.Empty{}, err } type pingPongServer struct {