grafana/k6 · error

can't convert method info: %w

Error message

can't convert method info: %w

What it means

After a successful server reflection handshake (connect with reflect: true), k6 converts the returned FileDescriptorSet into method/type descriptors; if protodesc.NewFiles rejects the descriptors (invalid or incomplete, e.g. unresolved imports) or a message registration fails, the error is wrapped as 'can't convert method info' (internal/js/modules/k6/grpc/client.go:285). The gRPC connection itself worked - it is the server's advertised schema that could not be processed.

Source

Thrown at internal/js/modules/k6/grpc/client.go:285

	c.addr = addr
	c.conn, err = grpcext.Dial(ctx, addr, c.types, opts...)
	if err != nil {
		return false, err
	}

	if !p.UseReflectionProtocol {
		return true, nil
	}

	ctx = metadata.NewOutgoingContext(ctx, p.ReflectionMetadata)

	fdset, err := c.conn.Reflect(ctx)
	if err != nil {
		return false, err
	}
	_, err = c.convertToMethodInfo(fdset)
	if err != nil {
		return false, fmt.Errorf("can't convert method info: %w", err)
	}

	return true, err
}

// HealthCheck checks if the server side is up and ready to serve responses
func (c *Client) HealthCheck(svc *string) (*grpcext.HealthCheckResponse, error) {
	var service string
	if svc != nil {
		service = *svc
	}
	return c.conn.HealthCheck(c.vu.Context(), service)
}

// Invoke creates and calls a unary RPC by fully qualified method name
func (c *Client) Invoke(
	method string,
	req sobek.Value,

View on GitHub (pinned to 93accf6570)

Solutions

  1. Fall back to a locally compiled protoset with client.load() instead of reflection
  2. Upgrade k6 - descriptor conversion handling has improved across releases
  3. If you own the server, ensure reflection serves complete descriptors (all imports); otherwise report the incompatibility with server and k6 versions

Example fix

// before
client.connect(addr, { reflect: true });

// after - fall back to a local protoset
client.load('./pb/service.protoset');
client.connect(addr, {});
Defensive patterns

Strategy: fallback

Try / catch

client.connect(addr, { reflect: true }).catch?.(() => {}) ?? null;
try {
  client.connect(addr, { reflect: true });
} catch (e) {
  if (/can't convert method info/.test(e.message)) {
    client.load('./pb/service.protoset'); // fallback: local descriptors
    client.connect(addr, {});
  } else throw e;
}

Prevention

When it happens

Trigger: client.connect(addr, { reflect: true }) against a server whose reflection returns descriptors with missing dependencies, or whose symbols conflict with definitions already registered by an earlier client.load() on the same client.

Common situations: Proxies or service meshes that implement gRPC reflection partially; servers whose runtime descriptors omit transitive imports; mixing client.load() and reflect: true on the same client instance.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/c169fb853e058956. Report an issue: GitHub.