apache/beam · error · java.lang.IllegalArgumentException

Pipeline options defaultEnvironmentConfig and…

Error message

Pipeline options defaultEnvironmentConfig and environmentOptions are mutually exclusive.

What it means

verifyEnvironmentOptions rejects pipelines that set both defaultEnvironmentConfig and environmentOptions, since they are two overlapping ways to describe the environment. It throws IllegalArgumentException before any environment is created.

Solutions

  1. Remove one of the two options — keep environmentOptions (and delete defaultEnvironmentConfig) or vice versa
  2. If migrating, port the values in defaultEnvironmentConfig into the equivalent environmentOptions entries
  3. Audit pipeline option templates/defaults so only one source is ever populated

Example fix

// before
options.setDefaultEnvironmentConfig("{\"command\":\"java -jar h.jar\"}");
options.setEnvironmentOptions(new String[]{"process_command=java -jar h.jar"});
// after
options.setEnvironmentOptions(new String[]{"process_command=java -jar h.jar"});
Defensive patterns

Strategy: validation

Validate before calling

if (options.getEnvironmentOptions() != null && !options.getEnvironmentOptions().isEmpty()
    && options.getDefaultEnvironmentConfig() != null) {
  throw new IllegalArgumentException("set only one of defaultEnvironmentConfig / environmentOptions");
}

Try / catch

try { env = Environments.createOrGetDefaultEnvironment(options); } catch (IllegalArgumentException e) { if (e.getMessage().contains("mutually exclusive")) { /* drop one option and retry */ } }

Prevention

When it happens

Trigger: Calling PortablePipelineOptions with both setDefaultEnvironmentConfig(...) and a non-empty setEnvironmentOptions(...) — commonly when legacy config from an old job is combined with new environment options.

Common situations: Migrating from defaultEnvironmentConfig (old style) to environmentOptions (new style) and leaving both; templated pipeline options merging defaults from different sources.

Related errors


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

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/Environments.java:621

    String assignments =
        PortablePipelineOptions.getEnvironmentOption(options, processVariablesOption);
    for (String assignment : assignments.split(",", -1)) {
      String[] tokens = assignment.split("=", -1);
      if (tokens.length == 1) {
        throw new IllegalArgumentException(
            String.format("Process environment variable '%s' is not assigned a value.", tokens[0]));
      }
      variables.put(tokens[0], tokens[1]);
    }
    return variables.build();
  }

  private static void verifyEnvironmentOptions(PortablePipelineOptions options) {
    if (options.getEnvironmentOptions() == null || options.getEnvironmentOptions().isEmpty()) {
      return;
    }
    if (!Strings.isNullOrEmpty(options.getDefaultEnvironmentConfig())) {
      throw new IllegalArgumentException(
          "Pipeline options defaultEnvironmentConfig and environmentOptions are mutually exclusive.");
    }
    Set<String> allowedOptions =
        allowedEnvironmentOptions.getOrDefault(
            options.getDefaultEnvironmentType(), ImmutableSet.of());
    for (String option : options.getEnvironmentOptions()) {
      String optionName = option.split("=", -1)[0];
      if (!allowedOptions.contains(optionName)) {
        throw new IllegalArgumentException(
            String.format(
                "Environment option '%s' is incompatible with environment type '%s'.",
                option, options.getDefaultEnvironmentType()));
      }
    }
  }
}

View on GitHub (pinned to 12126d8942)