apache/beam · error

error in starting expansion service, StartService(): %w

Error message

error in starting expansion service, StartService(): %w

What it means

After the expansion service runner is constructed, StartService() launches it (background JVM process listening on an endpoint). If startup fails — JVM exits, port binding fails, service times out — this error wraps the cause from startAutomatedJavaExpansionService.

Source

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

	jarPath, err := expansionx.GetBeamJar(gradleTarget, core.SdkVersion)
	if err != nil {
		return nil, "", err
	}

	if len(classpath) > 0 {
		jarPath, err = expansionx.MakeJar(jarPath, classpath)
		if err != nil {
			return nil, "", err
		}
	}

	serviceRunner, err := expansionx.NewExpansionServiceRunner(jarPath, "")
	if err != nil {
		return nil, "", fmt.Errorf("error in  startAutomatedJavaExpansionService(%s,%s): %w", gradleTarget, classpath, err)
	}
	err = serviceRunner.StartService()
	if err != nil {
		return nil, "", fmt.Errorf("error in starting expansion service, StartService(): %w", err)
	}
	stopFunc = serviceRunner.StopService
	address = serviceRunner.Endpoint()
	return stopFunc, address, nil
}

// QueryAutomatedExpansionService submits an external transform to be expanded by the
// expansion service and then eagerly materializes the artifacts for staging. 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 the HandlerParams after
// the prefix tag indicating the automated service is in use.
func QueryAutomatedExpansionService(ctx context.Context, p *HandlerParams) (*jobpb.ExpansionResponse, error) {
	// Strip auto: tag to get Gradle target
	tag, target := parseAddr(p.Config)
	// parse classpath namespace if present
	target, classpath := parseClasspath(target)

View on GitHub (pinned to 12126d8942)

Solutions

  1. Check the wrapped StartService error — often a port conflict; free the port or pick another.
  2. Verify Java version meets the expansion service jar's requirements.
  3. Retry after warm-up: first automated expansion downloads/builds the jar and can time out; pre-build it once.
  4. Run the expansion service manually (java -jar) and connect via a fixed endpoint.
  5. Inspect the expansion service's stderr/stdout logs for JVM classpath errors.

Example fix

// before
stop, addr, err := xlangx.QueryAutomatedExpansionService(ctx, req, nil, gradleTarget) // port 8097 busy
// after
// free the port or run the service yourself:
// java -jar expansion-service.jar 8098
res, err := xlangx.Expand(ctx, req, nil, "localhost:8098")
Defensive patterns

Strategy: retry

Validate before calling

conn, err := net.DialTimeout("tcp", "localhost:8097", 2*time.Second)
if err == nil { conn.Close(); return fmt.Errorf("port 8097 already in use") }

Try / catch

stop, addr, err := xlangx.QueryAutomatedExpansionService(ctx, req, o, target)
if err != nil {
	if errors.Is(err, context.DeadlineExceeded) {
		// first call may be slow due to gradle warm-up; retry once
	}
	return err
}
defer stop()

Prevention

When it happens

Trigger: QueryAutomatedExpansionService → startAutomatedJavaExpansionService when serviceRunner.StartService() returns non-nil: JVM startup failure, endpoint port already in use, classpath errors in the jar, or startup timeout.

Common situations: Port conflicts with other local services, Java version incompatibilities with the expansion jar, slow first-time Gradle builds exceeding startup timeouts, or firewall blocks on the chosen port.

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/3e8121c3242211c5. Report an issue: GitHub.