apache/beam · error

cannot use option zone with workerRegion; prefer either…

Error message

cannot use option zone with workerRegion; prefer either workerZone or workerRegion

What it means

validateWorkerSettings rejects a Dataflow job configuration that sets both the legacy --zone option and the newer workerRegion option, since the pipeline cannot be pinned to both a specific zone and a whole region. The error tells the user to migrate to workerZone (zonal) or keep workerRegion (regional).

Solutions

  1. Remove --zone and keep --worker_region (regional placement).
  2. Replace --zone with --worker_zone=us-central1-a if zonal placement is required.
  3. If zone is set only by stale code/config, unset it before building JobOptions.

Example fix

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

Strategy: validation

Validate before calling

if opts.Zone != "" && opts.WorkerRegion != "" {
    opts.WorkerZone = opts.Zone; opts.Zone = "" // normalize to worker_zone
}

Try / catch

if err := dataflowlib.ValidateWorkerSettings(ctx, opts); err != nil && strings.Contains(err.Error(), "option zone with workerRegion") {
    // strip legacy zone and retry translation
}

Prevention

When it happens

Trigger: JobOptions with Zone != "" AND WorkerRegion != ""; e.g. passing --zone=us-central1-a plus --worker_region=us-central1, or programmatically setting both fields on dataflow.JobOptions before Translate.

Common situations: Legacy scripts still passing --zone after the team added --worker_region for regional endpoints; mixing old and new pipeline options when upgrading Beam versions.

Related errors


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

Appendix: source

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

	addIfNonEmpty("region", opts.Region)
	addIfNonEmpty("zone", opts.Zone)
	addIfNonEmpty("worker_region", opts.WorkerRegion)
	addIfNonEmpty("worker_zone", opts.WorkerZone)
	addIfNonEmpty("network", opts.Network)
	addIfNonEmpty("subnetwork", opts.Subnetwork)
	addIfNonEmpty("machine_type", opts.MachineType)
	addIfNonEmpty("container_images", strings.Join(images, ","))
	addIfNonEmpty("temp_location", opts.TempLocation)

	for k, v := range opts.Options.Options {
		ret = append(ret, newDisplayData(k, "", "go_options", v))
	}
	return ret
}

func validateWorkerSettings(ctx context.Context, opts *JobOptions) error {
	if opts.Zone != "" && opts.WorkerRegion != "" {
		return errors.New("cannot use option zone with workerRegion; prefer either workerZone or workerRegion")
	}
	if opts.Zone != "" && opts.WorkerZone != "" {
		return errors.New("cannot use option zone with workerZone; prefer workerZone")
	}
	if opts.WorkerZone != "" && opts.WorkerRegion != "" {
		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")

View on GitHub (pinned to 12126d8942)