apache/beam · error
error reading --label flag as JSON
Error message
error reading --label flag as JSON
What it means
getJobOptions in the Dataflow runner parses the --label command-line flag as a JSON object mapping label keys to values. If json.Unmarshal of the flag's contents fails, the error is wrapped with this message and returned, aborting job option construction. Labels must be valid JSON of the form {"key":"value"}.
Source
Thrown at sdks/go/pkg/beam/runners/dataflow/dataflow.go:287
func getJobOptions(ctx context.Context, streaming bool) (*dataflowlib.JobOptions, error) {
project := gcpopts.GetProjectFromFlagOrEnvironment(ctx)
if project == "" {
return nil, errors.New("no Google Cloud project specified. Use --project=<project>")
}
region := gcpopts.GetRegion(ctx)
if region == "" {
return nil, errors.New("no Google Cloud region specified. Use --region=<region>. See https://cloud.google.com/dataflow/docs/concepts/regional-endpoints")
}
if *stagingLocation == "" {
return nil, errors.New("no GCS staging location specified. Use --staging_location=gs://<bucket>/<path>")
}
checkSoftDeletePolicyEnabled(ctx, *stagingLocation, "staging_location")
var jobLabels map[string]string
if *labels != "" {
if err := json.Unmarshal([]byte(*labels), &jobLabels); err != nil {
return nil, errors.Wrapf(err, "error reading --label flag as JSON")
}
}
if *cpuProfiling != "" {
perf.EnableProfCaptureHook("gcs_profile_writer", *cpuProfiling)
}
if *autoscalingAlgorithm != "" {
if *autoscalingAlgorithm != "NONE" && *autoscalingAlgorithm != "THROUGHPUT_BASED" {
return nil, errors.New("invalid autoscaling algorithm. Use --autoscaling_algorithm=(NONE|THROUGHPUT_BASED)")
}
}
if *flexRSGoal != "" {
switch *flexRSGoal {
case "FLEXRS_UNSPECIFIED", "FLEXRS_SPEED_OPTIMIZED", "FLEXRS_COST_OPTIMIZED":
// valid values
default:View on GitHub (pinned to 12126d8942)
Solutions
- Pass the --label flag as a valid JSON object, e.g. --label='{"env":"prod","team":"data"}'
- Validate the JSON locally with `echo '<value>' | jq .` before launching
- Check shell quoting: wrap the JSON in single quotes so double quotes survive
- If no labels are needed, omit the flag entirely (empty string is skipped)
Example fix
// before
--label=env=prod,team=data
// after
--label='{"env":"prod","team":"data"}' Defensive patterns
Strategy: validation
Validate before calling
if labels != "" {
var m map[string]string
if err := json.Unmarshal([]byte(labels), &m); err != nil {
return fmt.Errorf("--label flag is not valid JSON: %w", err)
}
} Try / catch
if err := run(); err != nil {
if strings.Contains(err.Error(), "--label flag") {
log.Fatalf("fix --label JSON: %v", err)
}
} Prevention
- Always pass --label as a double-quoted JSON object in single-quoted shell args
- Validate flag JSON with jq before launching
- Never pass key=value pairs where JSON objects are expected
- Keep label definitions in config files parsed once and validated at startup
When it happens
Trigger: Launching a Dataflow pipeline with a non-empty --label flag whose value is not valid JSON (e.g. single quotes, unquoted keys, trailing commas, or a plain key=value string).
Common situations: Shell quoting issues where single-quoted JSON is passed but interpreted incorrectly, users passing key=value pairs instead of a JSON object, copying labels from documentation with markdown quotes, or CI variables containing escaped quotes.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- error reading --transform_name_mapping flag as JSON
- invalid autoscaling algorithm. Use --autoscaling_algorithm=(
- provided transform_name_mapping without setting the --update
- exactly one of usePublicIPs and noUsePublicIPs must be true,
- invalid flex resource scheduling goal. Got %q; Use --flexrs_
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/7877aae3acb95ce8.
Report an issue: GitHub.