apache/beam · error

failed to start environment

Error message

failed to start environment %v for job %v: %w

What it means

RunPipeline starts every environment of the job via runEnvironment. If any environment fails to start, the job is marked Failed with this wrapper error carrying the environment ID, job, and the underlying cause (e.g. docker or process launch failure).

Solutions

  1. Read the wrapped cause (%w) to identify the environment startup failure
  2. Verify Docker/process prerequisites before launching prism
  3. Fix the pipeline environment config (image, URN) as indicated by the cause
  4. Retry after environment fixes; check worker logs for details
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: docker reachable + image present
checkDocker(); checkImage(sdkImage)

Try / catch

if err := j.WaitUntilDone(ctx); err != nil {
  if strings.Contains(err.Error(), "failed to start environment") {
    log.Fatalf("environment startup failed: %v", err)
  }
}

Prevention

When it happens

Trigger: Any error returned by runEnvironment for any envID — docker connect/create/start failure, unimplemented environment URN, or process launch failure.

Common situations: Docker unavailable on the runner host, bad container image, or unsupported environment type in the submitted pipeline.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/runners/prism/internal/execute.go:58

// RunPipeline starts the main thread fo executing this job.
// It's analoguous to the manager side process for a distributed pipeline.
// It will begin "workers"
func RunPipeline(j *jobservices.Job) {
	j.SendMsg("starting " + j.String())
	j.Start()

	// In a "proper" runner, we'd iterate through all the
	// environments, and start up docker containers, but
	// here, we only want and need the go one, operating
	// in loopback mode.
	envs := j.Pipeline.GetComponents().GetEnvironments()
	wks := map[string]*worker.W{}
	for envID := range envs {
		wk := j.MakeWorker(envID)
		wks[envID] = wk
		if err := runEnvironment(j.RootCtx, j, envID, wk); err != nil {
			j.Failed(fmt.Errorf("failed to start environment %v for job %v: %w", envID, j, err))
			return
		}
		// Check for connection succeeding after we've created the environment successfully.
		timeout := 1 * time.Minute
		time.AfterFunc(timeout, func() {
			if wk.Connected() || wk.Stopped() {
				return
			}
			err := fmt.Errorf("prism %v didn't get control connection to %v after %v", wk, wk.Endpoint(), timeout)
			j.Failed(err)
			j.CancelFn(err)
		})
	}

	// When this function exits, we cancel the context to clear
	// any related job resources.
	defer func() {
		j.CancelFn(fmt.Errorf("runPipeline returned, cleaning up"))

View on GitHub (pinned to 12126d8942)