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
- Set ShutdownMode only to init.Terminate or init.Return.
- Remove any custom assignment if you don't need to change shutdown behavior; keep the default.
- 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
- Only assign the two exported constants to ShutdownMode
- Never read ShutdownMode values from unvalidated config
- Set ShutdownMode once, early, and treat it as immutable
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
- empty port
- internal: log message buffer closed
- side input closed
- trigger.AfterCount(%v) must be a positive integer
- can't apply processing delay of less than a millisecond. Got
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/de52dc2d030fe8d8.
Report an issue: GitHub.