apache/beam · error

unknown ShutdownMode: %v

Error message

unknown ShutdownMode: %v

What it means

beam.Init() takes over main for Beam workers and installs an exit hook that decides whether the process terminates hard (os.Exit) or returns control. Only ShutdownMode Terminate and Return are defined; any other value is a programming error, so the code panics with the offending value.

Source

Thrown at sdks/go/pkg/beam/core/runtime/harness/init/init.go:138

			experiments = strings.Split(e, ",")
		}
		// TODO(zechenj18) 2023-12-07: Remove once the data sampling URN is properly sent in via the capabilities
		if slices.Contains(experiments, "enable_data_sampling") {
			runnerCapabilities = append(runnerCapabilities, graphx.URNDataSampling)
		}
	}

	defer func() {
		if r := recover(); r != nil {
			fmt.Fprintf(os.Stderr, "Worker panic: %v\n", r)
			debug.PrintStack()
			switch ShutdownMode {
			case Terminate:
				os.Exit(2)
			case Return:
				return
			default:
				panic(fmt.Sprintf("unknown ShutdownMode: %v", ShutdownMode))
			}
		}
	}()

	// Since Init() is hijacking main, it's appropriate to do as main
	// does, and establish the background context here.
	// We produce a cancelFn here so runs in Loopback mode and similar can clean up
	// any leftover goroutines.
	ctx, cancelFn := context.WithCancel(context.Background())
	defer cancelFn()
	ctx = grpcx.WriteWorkerID(ctx, *id)
	memLimit := memoryLimit()
	if err := syscallx.SetProcessMemoryCeiling(memLimit, memLimit); err != nil && err != syscallx.ErrUnsupported {
		fmt.Println("Error Setting Rlimit ", err)
	}

	options := harness.Options{
		StatusEndpoint:     statusEndpoint,

View on GitHub (pinned to 12126d8942)

Solutions

  1. Set ShutdownMode only to init.Terminate or init.Return.
  2. Remove any custom assignment if you don't need to change shutdown behavior; keep the default.
  3. Audit for concurrent writes to ShutdownMode; make the assignment once at startup.

Example fix

// before
init.ShutdownMode = init.ShutdownMode(3)
// after
init.ShutdownMode = init.Return // or init.Terminate
Defensive patterns

Strategy: validation

Validate before calling

if init.ShutdownMode != init.Terminate && init.ShutdownMode != init.Return {
    panic("ShutdownMode must be init.Terminate or init.Return")
}

Try / catch

defer func() { if r := recover(); r != nil { log.Fatalf("shutdown mode error: %v", r) } }()

Prevention

When it happens

Trigger: Assigning any value to the harness init.ShutdownMode package variable other than init.Terminate or init.Return before/while the deferred exit hook runs in the path guarded by the harness Main.

Common situations: Custom worker code setting ShutdownMode to an out-of-range integer or an unexported/foreign type; copy-paste code importing the wrong ShutdownMode constant; concurrent code mutating ShutdownMode mid-run.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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