micro/go-micro · error
connect reflected grpc target %s: %w
Error message
connect reflected grpc target %s: %w
What it means
reflectedGRPCTools establishes a gRPC client connection to the configured reflection target using grpc.NewClient with the target's DialOptions (defaulting to insecure credentials). If client creation fails, the error is wrapped with the target address. This is the entry point for discovering tools via gRPC server reflection.
Source
Thrown at gateway/mcp/grpcreflect.go:68
}
return nil
}
func (s *Server) reflectedGRPCTools(target ReflectedGRPCTarget) ([]*Tool, error) {
timeout := target.Timeout
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 {
continueView on GitHub (pinned to 24529f1404)
Solutions
- Check the wrapped (%w) grpc error; correct target.Address format (e.g. 'dns:///host:port' or 'host:port').
- Review target.DialOptions for invalid or mutually conflicting options.
- If the endpoint is plaintext, either leave DialOptions empty (defaults to insecure) or pass grpc.WithTransportCredentials(insecure.NewCredentials()) explicitly.
- Upgrade/verify grpc-go version compatibility if NewClient (added in grpc-go 1.63) behaves differently than grpc.Dial in your setup.
Example fix
// before
target.DialOptions = []grpc.DialOption{grpc.WithTransportCredentials(credentials.NewTLS(nil))}
// after
target.DialOptions = nil // falls back to insecure default, or supply correctly configured TLS creds Defensive patterns
Strategy: validation
Validate before calling
if target.Address == "" || (!strings.Contains(target.Address, ":") && !strings.Contains(target.Address, "/")) {
return fmt.Errorf("invalid grpc target address %q", target.Address)
} Type guard
func validGRPCTarget(t GRPCTarget) bool {
return t.Address != "" && (len(t.DialOptions) == 0 || t.DialOptions != nil)
} Try / catch
conn, err := grpc.NewClient(target.Address, dialOpts...)
if err != nil {
return fmt.Errorf("target %s rejected by grpc.NewClient: %w", target.Address, err)
}
defer conn.Close() Prevention
- Validate target.Address format before discovery.
- Prefer leaving DialOptions empty to get the insecure default in dev.
- Keep grpc-go >= 1.63 where grpc.NewClient is the supported dial API.
- Confirm the target host:port is reachable before configuring it.
When it happens
Trigger: Calling reflectedGRPCTools (via discoverReflectedGRPC) where target.DialOptions are invalid or grpc.NewClient rejects the target.Address/configuration.
Common situations: Malformed target address string (bad scheme/host); unsupported or conflicting grpc.DialOption combinations; attempting TLS credentials against a target that needs a different scheme (dns:/// vs passthrough).
Related errors
- reflect 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/4d5c7a988a44564d.
Report an issue: GitHub.