apache/beam · error

experiment worker_region and option Zone are mutually…

Error message

experiment worker_region and option Zone are mutually exclusive

What it means

validateWorkerSettings rejects a job that enables the worker_region experiment while also setting the deprecated zone option. Regional placement declared via experiments cannot coexist with zonal placement via --zone.

Solutions

  1. Remove --zone; if zonal placement is needed use --worker_zone (without the experiment).
  2. If regional placement is needed, drop --zone and use the --worker_region option instead of the experiment.
  3. Migrate away from both the experiment form and --zone to the single --worker_region option.

Example fix

// before
// --experiment=worker_region=us-central1 --zone=us-central1-a
// after
// --worker_region=us-central1   (regional) or --worker_zone=us-central1-a (zonal)
Defensive patterns

Strategy: validation

Validate before calling

hasExp := false
for _, e := range opts.Experiments {
    if strings.HasPrefix(e, "worker_region") { hasExp = true }
}
if hasExp && opts.Zone != "" {
    opts.Zone = "" // legacy zone conflicts with regional experiment
}

Try / catch

if err := dataflowlib.ValidateWorkerSettings(ctx, opts); err != nil && strings.Contains(err.Error(), "experiment worker_region and option Zone") {
    // drop legacy zone (or the experiment) and retry
}

Prevention

When it happens

Trigger: JobOptions.Experiments contains a string with prefix "worker_region" AND opts.Zone != "" during Translate. Note the zone check happens before zone is deprecated-normalized into WorkerZone.

Common situations: Old scripts using --experiment=worker_region=... plus legacy --zone; template merges keeping the deprecated flag.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/runners/dataflow/dataflowlib/job.go:427

		return errors.New("workerRegion and workerZone options are mutually exclusive")
	}

	hasExperimentWorkerRegion := false
	for _, experiment := range opts.Experiments {
		if strings.HasPrefix(experiment, "worker_region") {
			hasExperimentWorkerRegion = true
			break
		}
	}

	if hasExperimentWorkerRegion && opts.WorkerRegion != "" {
		return errors.New("experiment worker_region and option workerRegion are mutually exclusive")
	}
	if hasExperimentWorkerRegion && opts.WorkerZone != "" {
		return errors.New("experiment worker_region and option workerZone are mutually exclusive")
	}
	if hasExperimentWorkerRegion && opts.Zone != "" {
		return errors.New("experiment worker_region and option Zone are mutually exclusive")
	}

	if opts.Zone != "" {
		log.Warn(ctx, "Option --zone is deprecated. Please use --workerZone instead.")
		opts.WorkerZone = opts.Zone
		opts.Zone = ""
	}

	numWorkers := opts.NumWorkers
	maxNumWorkers := opts.MaxNumWorkers
	if numWorkers < 0 {
		return fmt.Errorf("num_workers (%d) cannot be negative", numWorkers)
	}
	if maxNumWorkers < 0 {
		return fmt.Errorf("max_num_workers (%d) cannot be negative", maxNumWorkers)
	}
	if numWorkers > 0 && maxNumWorkers > 0 && numWorkers > maxNumWorkers {
		return fmt.Errorf("num_workers (%d) cannot exceed max_num_workers (%d)", numWorkers, maxNumWorkers)

View on GitHub (pinned to 12126d8942)