micro/go-micro · error
reflect grpc target %s: %w
Error message
reflect grpc target %s: %w
What it means
After connecting, reflectedGRPCTools calls loadReflectedFiles to perform gRPC server reflection (list services + fetch file descriptors). Any failure inside reflection is wrapped with the target address in this error. The connection itself succeeded; the reflection RPC exchange failed.
Source
Thrown at gateway/mcp/grpcreflect.go:74
if timeout == 0 {
timeout = 10 * time.Second
}
ctx, cancel := context.WithTimeout(s.opts.Context, timeout)
defer cancel()
dialOpts := target.DialOptions
if len(dialOpts) == 0 {
dialOpts = []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
}
conn, err := grpc.NewClient(target.Address, dialOpts...)
if err != nil {
return nil, fmt.Errorf("connect reflected grpc target %s: %w", target.Address, err)
}
defer conn.Close()
files, services, err := loadReflectedFiles(ctx, conn)
if err != nil {
return nil, fmt.Errorf("reflect grpc target %s: %w", target.Address, err)
}
prefix := target.Name
if prefix == "" {
prefix = sanitizeToolPart(target.Address)
}
var out []*Tool
for _, serviceName := range services {
desc, err := files.FindDescriptorByName(protoreflect.FullName(serviceName))
if err != nil {
continue
}
svc, ok := desc.(protoreflect.ServiceDescriptor)
if !ok {
continue
}
for i := 0; i < svc.Methods().Len(); i++ {View on GitHub (pinned to 24529f1404)
Solutions
- Enable reflection on the target server: reflection.Register(server) after NewServer, or run with a reflection-enabled option.
- Verify the wrapped (%w) inner error to distinguish NotFound (no reflection service) from timeouts/cancellations.
- Check network reachability and that ctx is not cancelled before loadReflectedFiles completes.
- If the server cannot enable reflection, provide descriptor files instead of relying on reflection discovery.
Example fix
// before server := grpc.NewServer() server.Serve(lis) // no reflection // after server := grpc.NewServer() reflection.Register(server) server.Serve(lis)
Defensive patterns
Strategy: fallback
Validate before calling
// probe reflection support before full discovery
conn, _ := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
client := grpcreflection.NewReflectionClientAuto(conn)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if _, err := client.ListServices(ctx, &refpb.ListServicesRequest{}); err != nil {
return fmt.Errorf("target %s lacks reflection: %w", addr, err)
} Try / catch
tools, err := reflectedGRPCTools(ctx, target)
if err != nil && strings.Contains(err.Error(), "reflect grpc target") {
tools = loadToolsFromStaticDescriptors(target) // fallback path
} Prevention
- Enable reflection.Register(server) on every gRPC server you discover from.
- Smoke-test reflection with grpcurl before wiring discovery.
- Provide static descriptor sets as a fallback for servers without reflection.
- Ensure the context has enough deadline for list + file-descriptor round trips.
When it happens
Trigger: grpc.NewClient succeeds but loadReflectedFiles fails: the server does not implement gRPC reflection, reflection RPCs time out, or the reflection stream returns an error.
Common situations: Target server was started without grpc reflection (reflection.Register(server) missing or grpcui not enabled); a proxy/firewall blocking the reflection service; server shutting down mid-reflection.
Related errors
- connect reflected grpc target %s: %w
- reflection list services returned %T
- reflection lookup for %s returned %T
- subscriber %v takes wrong number of args: %v required signat
- subscriber %v argument type not exported: %v
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/cd70a1ff900a751d.
Report an issue: GitHub.