apache/beam · error

unable to connect to expansion service at %v

Error message

unable to connect to expansion service at %v

What it means

Raised in xlangx.QueryExpansionService when grpc.Dial cannot establish a connection to the expansion service address in p.Config. It indicates the gRPC client could not even be created/dialed for the ExpansionRequest, and the error is annotated with the request for context.

Source

Thrown at sdks/go/pkg/beam/core/runtime/xlangx/expand.go:165

	})
}

// QueryExpansionService submits an external transform to be expanded by the
// expansion service. The given transform should be the external transform, and
// the components are any additional components necessary for the pipeline
// snippet.
//
// The address to be queried is determined by the Config field of HandlerParams.
//
// This HandlerFunc is exported to simplify building custom handler functions
// that do end up calling a Beam ExpansionService, either as a fallback or
// as part of normal flow.
func QueryExpansionService(ctx context.Context, p *HandlerParams) (*jobpb.ExpansionResponse, error) {
	req := p.Req
	// Setting grpc client
	conn, err := grpc.Dial(p.Config, grpc.WithInsecure())
	if err != nil {
		err = errors.Wrapf(err, "unable to connect to expansion service at %v", p.Config)
		return nil, errors.WithContextf(err, "expanding transform with ExpansionRequest: %v", req)
	}
	defer conn.Close()
	client := jobpb.NewExpansionServiceClient(conn)

	// Handling ExpansionResponse
	retryOpts := []retry.Option{
		retry.Attempts(maxRetries),
		retry.DelayType(func(n uint, err error, config *retry.Config) time.Duration {
			if n == 0 {
				return time.Second
			}
			return retry.BackOffDelay(n, err, config)
		}),
	}
	var res *jobpb.ExpansionResponse
	err = retry.Do(func() error {
		res, err = client.Expand(ctx, req)

View on GitHub (pinned to 12126d8942)

Solutions

  1. Verify the expansion service address is correct and reachable (host:port), e.g. with grpcurl or nc
  2. Start the expansion service and confirm it is listening on the configured port
  3. Check network/firewall/DNS rules between the Go pipeline and the service host
  4. If relying on QueryAutomatedExpansionService, confirm the service JAR/download succeeded and the port is free

Example fix

// before
xlangx.QueryPythonExpansionService(ctx, req, "localhost:9999") // nothing listening
// after
// start: python -m apache_beam.runners.portability.expansion_service_main --port 5555
xlangx.QueryPythonExpansionService(ctx, req, "localhost:5555")
Defensive patterns

Strategy: validation

Validate before calling

host, port, err := net.SplitHostPort(addr)
if err != nil {
    return fmt.Errorf("bad expansion service address %q: %w", addr, err)
}
if conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), 2*time.Second); err != nil {
    return fmt.Errorf("expansion service not reachable at %s: %w", addr, err)
} else {
    conn.Close()
}

Try / catch

res, err := xlangx.QueryExpansionService(ctx, params)
if err != nil {
    return fmt.Errorf("expansion service %s unreachable: %w", params.Config, err)
}

Prevention

When it happens

Trigger: Calling QueryPythonExpansionService or QueryAutomatedExpansionService with an expansion service address that is malformed, unreachable, or refused the gRPC dial.

Common situations: Expansion service not started or crashed before use; wrong host/port passed via expansion service config; firewall or DNS issues; specifying an invalid URL such as missing port or scheme.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/7435200bf5bb0640. Report an issue: GitHub.