{"record":{"id":"6f4967e0071550e1","repo":"apache/beam","slug":"experimental-host-can-only-be-used-with-instance-id","errorCode":null,"errorMessage":"Experimental host can only be used with instance id: + EXPERIMENTAL_HOST_INSTANCE_ID","messagePattern":"Experimental host can only be used with instance id: \\+ EXPERIMENTAL_HOST_INSTANCE_ID","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerAccessor.java","lineNumber":271,"sourceCode":"\n    ValueProvider<String> projectId = spannerConfig.getProjectId();\n    if (projectId != null) {\n      builder.setProjectId(projectId.get());\n    }\n    ServiceFactory<Spanner, SpannerOptions> serviceFactory = spannerConfig.getServiceFactory();\n    if (serviceFactory != null) {\n      builder.setServiceFactory(serviceFactory);\n    }\n    builder.setHost(spannerConfig.getHostValue());\n\n    ValueProvider<String> experimentalHost = spannerConfig.getExperimentalHost();\n    if (experimentalHost != null && !Strings.isNullOrEmpty(experimentalHost.get())) {\n      builder.setExperimentalHost(experimentalHost.get());\n      ValueProvider<Boolean> plainText = spannerConfig.getPlainText();\n      ValueProvider<String> instanceId = spannerConfig.getInstanceId();\n      if (Strings.isNullOrEmpty(instanceId.get())\n          || !instanceId.get().equals(EXPERIMENTAL_HOST_INSTANCE_ID)) {\n        throw new IllegalArgumentException(\n            \"Experimental host can only be used with instance id: \"\n                + EXPERIMENTAL_HOST_INSTANCE_ID);\n      }\n      if (plainText != null && Boolean.TRUE.equals(plainText.get())) {\n        builder.setChannelConfigurator(b -> b.usePlaintext());\n      }\n      ValueProvider<String> clientCert = spannerConfig.getClientCertPath();\n      ValueProvider<String> clientKey = spannerConfig.getClientCertKeyPath();\n      if (clientCert != null\n          && clientKey != null\n          && clientCert.isAccessible()\n          && clientKey.isAccessible()\n          && !Strings.isNullOrEmpty(clientCert.get())\n          && !Strings.isNullOrEmpty(clientKey.get())) {\n        builder.useClientCert(clientCert.get(), clientKey.get());\n      }\n    }\n","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerAccessor.java#L253-L289","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove the experimentalHost option to use the standard Spanner endpoint","Set the instance id exactly to EXPERIMENTAL_HOST_INSTANCE_ID if you truly intend to use the experimental host","Check pipeline options/argv for stray --experimentalHost flags","Verify which SpannerAccessor/SpannerConfig instance is being built and its instanceId value"],"exampleFix":"// before\n--experimentalHost=staging.googleapis.com --spannerInstanceId=prod-instance\n// after\n--spannerInstanceId=prod-instance  // experimentalHost removed","handlingStrategy":"validation","validationCode":"if (experimentalHost != null && !experimentalHost.isEmpty()\n    && !EXPERIMENTAL_HOST_INSTANCE_ID.equals(instanceId)) {\n  throw new IllegalArgumentException(\"experimentalHost requires instance id \" + EXPERIMENTAL_HOST_INSTANCE_ID);\n}","typeGuard":null,"tryCatchPattern":"try { accessor = SpannerAccessor.getOrCreate(config); } catch (IllegalArgumentException e) { /* strip experimentalHost and retry */ }","preventionTips":["Never set experimentalHost in production configs","Audit pipeline option defaults for stray experimental flags","Use separate option profiles for experimental vs production runs"],"tags":["java","spanner","configuration","experimental"],"backgroundTag":"conflicting-config-options","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}