apache/beam · error · RuntimeException
Invalid host/port in BigtableConfig
Error message
Invalid host/port in BigtableConfig
What it means
When a Bigtable emulator host:port is configured, buildBigtableDataSettings parses it as host and port. If the string after the last ':' is not a valid integer port (or the string has no host part at all), the NumberFormatException/IndexOutOfBoundsException is rethrown as this RuntimeException.
Solutions
- Fix the emulator address to 'host:port' format, e.g. "localhost:8086", in your BigtableConfig/executor config.
- Validate the endpoint before building: split on ':' and check Integer.parseInt succeeds.
- If you meant a real Bigtable instance, remove the emulator host/port so the code takes the BigtableDataSettings.newBuilder() path.
Example fix
// before
builder.setHostAndPort("localhost"); // throws
// after
builder.setHostAndPort("localhost:8086"); Defensive patterns
Strategy: validation
Validate before calling
String[] parts = hostAndPort.split(":");
if (parts.length != 2 || parts[0].isEmpty()) throw new IllegalArgumentException("Emulator must be host:port");
int port = Integer.parseInt(parts[1]); // throws clear NumberFormatException Type guard
boolean isValidHostPort(String s) { int i = s.lastIndexOf(':'); if (i <= 0) return false; try { Integer.parseInt(s.substring(i + 1)); return true; } catch (NumberFormatException e) { return false; } } Try / catch
try { settings = translator.buildBigtableDataSettings(config, options); } catch (RuntimeException e) { if (e.getMessage().contains("Invalid host/port")) { ... } throw e; } Prevention
- Use BigtableEmulatorOptions/helpers or the emulator's documented address localhost:8086.
- Validate emulator env vars at job-argument parsing time.
- Keep host and port as separate config fields to avoid string parsing.
When it happens
Trigger: Setting the Bigtable config's hostAndPort (emulator target) to a malformed value like "localhost" (no port), "localhost:notaport", or "::bad" and then translating the config into BigtableDataSettings.
Common situations: Typo in emulator endpoint; environment variable for the emulator host missing its port; copy-paste dropping the :8086; wrong variable interpolated into the config.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Allow list file does not exist
- Ambiguous expression type (perhaps missing quoting?)
- Approximate Nearest Neighbor Search (ANNS) field must be…
- BigQuery temp location expected a valid 'gs://' path, but…
- Bigtable location must be in the following format…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b6d1ebf7459430dc.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableConfigTranslator.java:118
return buildBigtableDataSettings(config, pipelineOptions).build();
}
private static BigtableDataSettings.Builder buildBigtableDataSettings(
BigtableConfig config, PipelineOptions pipelineOptions) throws IOException {
BigtableDataSettings.Builder dataBuilder;
boolean emulator = false;
if (!Strings.isNullOrEmpty(config.getEmulatorHost())) {
emulator = true;
String hostAndPort = config.getEmulatorHost();
try {
int lastIndexOfCol = hostAndPort.lastIndexOf(":");
int port = Integer.parseInt(hostAndPort.substring(lastIndexOfCol + 1));
dataBuilder =
BigtableDataSettings.newBuilderForEmulator(
hostAndPort.substring(0, lastIndexOfCol), port);
} catch (NumberFormatException | IndexOutOfBoundsException ex) {
throw new RuntimeException("Invalid host/port in BigtableConfig " + hostAndPort);
}
} else {
dataBuilder = BigtableDataSettings.newBuilder();
}
// Configure target
dataBuilder
.setProjectId(Objects.requireNonNull(config.getProjectId().get()))
.setInstanceId(Objects.requireNonNull(config.getInstanceId().get()));
if (config.getAppProfileId() != null
&& !Strings.isNullOrEmpty(config.getAppProfileId().get())) {
dataBuilder.setAppProfileId(Objects.requireNonNull(config.getAppProfileId().get()));
}
// Skip resetting the credentials if it's connected to an emulator
if (!emulator) {
if (pipelineOptions.as(GcpOptions.class).getGcpCredential() != null) {
dataBuilderView on GitHub (pinned to 12126d8942)