apache/beam · error

environment with urn unimplemented

Error message

environment %v with urn %v unimplemented

What it means

runEnvironment dispatches on the environment type of a pipeline stage. The default case rejects environment payloads prism does not implement (anything other than external, docker, or process environments), reporting the environment proto and its URN.

Solutions

  1. Ensure the pipeline uses an external, docker, or process environment (SDK harness container image)
  2. Regenerate the pipeline with a newer SDK that emits external/docker environments
  3. If using legacy embedded environments, run via Flink/Spark-style portable submission with a proper harness image
  4. Check selectAnyOfEnv ordering in environments.go and explicitly set an external environment

Example fix

// before: pipeline with no environment set (empty URN)
// after: attach an external docker environment
env := pipepb.NewEnvironment("py-sdk", "beam:env:docker:v1",
  &pipepb.DockerPayload{ContainerImage: "apache/beam_python3.11_sdk:latest"}, ...)
Defensive patterns

Strategy: validation

Validate before calling

urn := env.GetUrn()
supported := map[string]bool{"beam:env:docker:v1": true, "beam:env:process:v1": true, "beam:env:external:v1": true}
if !supported[urn] {
  return fmt.Errorf("environment URN %q unsupported by prism runner", urn)
}

Prevention

When it happens

Trigger: Submitting a pipeline whose environment URN is not one of the supported docker/process/external types — e.g. legacy embedded Python/Java environments or an AnyOf environment that only ranks to an unknown type.

Common situations: Older SDK pipeline representations without container images, pipelines converted through tools that emit unknown environment URNs, or cross-language pipelines using environments prism lacks support for.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/runners/prism/internal/environments.go:95

		dp := &pipepb.DockerPayload{}
		if err := (proto.UnmarshalOptions{}).Unmarshal(e.GetPayload(), dp); err != nil {
			logger.Error("unmarshaling docker environment payload", "error", err)
			return err
		}
		return dockerEnvironment(ctx, logger, dp, wk, wk.ArtifactEndpoint)
	case urns.EnvProcess:
		pp := &pipepb.ProcessPayload{}
		if err := (proto.UnmarshalOptions{}).Unmarshal(e.GetPayload(), pp); err != nil {
			logger.Error("unmarshaling process environment payload", "error", err)
			return err
		}
		go func() {
			processEnvironment(ctx, logger, pp, wk)
			logger.Debug("environment stopped", slog.String("job", j.String()))
		}()
		return nil
	default:
		return fmt.Errorf("environment %v with urn %v unimplemented", env, e.GetUrn())
	}
}

func selectAnyOfEnv(ap *pipepb.AnyOfEnvironmentPayload) *pipepb.Environment {
	// Prefer external, then process, then docker, unknown environments are 0.
	ranks := map[string]int{
		urns.EnvDocker:   1,
		urns.EnvProcess:  5,
		urns.EnvExternal: 10,
	}

	envs := ap.GetEnvironments()

	slices.SortStableFunc(envs, func(a, b *pipepb.Environment) int {
		rankA := ranks[a.GetUrn()]
		rankB := ranks[b.GetUrn()]

		// Reverse the comparison so our favourite is at the front

View on GitHub (pinned to 12126d8942)