apache/beam · error · IllegalArgumentException

Experimental host can only be used with instance id: + EXPER

Error message

Experimental host can only be used with instance id: + EXPERIMENTAL_HOST_INSTANCE_ID

What it means

SpannerAccessor.buildSpannerOptions() allows an experimental Spanner host endpoint only as a special test/experiment path: when the experimentalHost option is set, the instance id must equal EXPERIMENTAL_HOST_INSTANCE_ID; otherwise it throws IllegalArgumentException. This guards the experimental feature so it cannot be accidentally combined with production instance configurations.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerAccessor.java:271

    ValueProvider<String> projectId = spannerConfig.getProjectId();
    if (projectId != null) {
      builder.setProjectId(projectId.get());
    }
    ServiceFactory<Spanner, SpannerOptions> serviceFactory = spannerConfig.getServiceFactory();
    if (serviceFactory != null) {
      builder.setServiceFactory(serviceFactory);
    }
    builder.setHost(spannerConfig.getHostValue());

    ValueProvider<String> experimentalHost = spannerConfig.getExperimentalHost();
    if (experimentalHost != null && !Strings.isNullOrEmpty(experimentalHost.get())) {
      builder.setExperimentalHost(experimentalHost.get());
      ValueProvider<Boolean> plainText = spannerConfig.getPlainText();
      ValueProvider<String> instanceId = spannerConfig.getInstanceId();
      if (Strings.isNullOrEmpty(instanceId.get())
          || !instanceId.get().equals(EXPERIMENTAL_HOST_INSTANCE_ID)) {
        throw new IllegalArgumentException(
            "Experimental host can only be used with instance id: "
                + EXPERIMENTAL_HOST_INSTANCE_ID);
      }
      if (plainText != null && Boolean.TRUE.equals(plainText.get())) {
        builder.setChannelConfigurator(b -> b.usePlaintext());
      }
      ValueProvider<String> clientCert = spannerConfig.getClientCertPath();
      ValueProvider<String> clientKey = spannerConfig.getClientCertKeyPath();
      if (clientCert != null
          && clientKey != null
          && clientCert.isAccessible()
          && clientKey.isAccessible()
          && !Strings.isNullOrEmpty(clientCert.get())
          && !Strings.isNullOrEmpty(clientKey.get())) {
        builder.useClientCert(clientCert.get(), clientKey.get());
      }
    }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove the experimentalHost option to use the standard Spanner endpoint
  2. Set the instance id exactly to EXPERIMENTAL_HOST_INSTANCE_ID if you truly intend to use the experimental host
  3. Check pipeline options/argv for stray --experimentalHost flags
  4. Verify which SpannerAccessor/SpannerConfig instance is being built and its instanceId value

Example fix

// before
--experimentalHost=staging.googleapis.com --spannerInstanceId=prod-instance
// after
--spannerInstanceId=prod-instance  // experimentalHost removed
Defensive patterns

Strategy: validation

Validate before calling

if (experimentalHost != null && !experimentalHost.isEmpty()
    && !EXPERIMENTAL_HOST_INSTANCE_ID.equals(instanceId)) {
  throw new IllegalArgumentException("experimentalHost requires instance id " + EXPERIMENTAL_HOST_INSTANCE_ID);
}

Try / catch

try { accessor = SpannerAccessor.getOrCreate(config); } catch (IllegalArgumentException e) { /* strip experimentalHost and retry */ }

Prevention

When it happens

Trigger: Setting SpannerConfig.experimentalHost (e.g. via --experimentalHost or withExperimentalHost) to a non-empty value while spannerConfig.instanceId is missing or does not equal EXPERIMENTAL_HOST_INSTANCE_ID.

Common situations: Copy-pasting experimental host flags from internal docs/testing into production pipeline options; leaving an experimental host env/option set in CI; mixing standard instance configs with an experimental endpoint.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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