apache/beam · error · IllegalArgumentException
databaseId can't be empty
Error message
databaseId can't be empty
What it means
SpannerTransformRegistrar's checkMandatoryFields() validates that the Spanner connector configuration includes a projectId, databaseId, and instanceId before building any read/write transform. This error is thrown when the databaseId field is set to an empty string (or never set), because a Cloud Spanner database path cannot be constructed without it. It is a fail-fast guard so the job fails at pipeline-construction time rather than deep inside the runner.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerTransformRegistrar.java:128
public void setPlainText(@Nullable Boolean plainText) {
this.plainText = plainText;
}
public void setClientCertPath(@Nullable String clientCertPath) {
this.clientCertPath = clientCertPath;
}
public void setClientCertKeyPath(@Nullable String clientCertKeyPath) {
this.clientCertKeyPath = clientCertKeyPath;
}
void checkMandatoryFields() {
if (projectId.isEmpty()) {
throw new IllegalArgumentException("projectId can't be empty");
}
if (databaseId.isEmpty()) {
throw new IllegalArgumentException("databaseId can't be empty");
}
if (instanceId.isEmpty()) {
throw new IllegalArgumentException("instanceId can't be empty");
}
if ((clientCertPath != null) != (clientCertKeyPath != null)) {
throw new IllegalArgumentException(
"Both clientCertPath and clientCertKeyPath must be specified together.");
}
}
}
public static class ReadBuilder
implements ExternalTransformBuilder<ReadBuilder.Configuration, PBegin, PCollection<Row>> {
public static class Configuration extends CrossLanguageConfiguration {
// TODO: https://github.com/apache/beam/issues/20415 Come up with something to determine
// schema without this explicit parameter
private Schema schema = Schema.builder().build();View on GitHub (pinned to 12126d8942)
Solutions
- Call .withDatabaseId("<your-database>") on the Spanner builder with a non-empty database name.
- If the value comes from an option/env var, check it is non-empty before building the transform (e.g. requireNonNull(options.getSpannerDatabase()).isEmpty() guard).
- Verify the database exists with `gcloud spanner databases list --instance=<instance>` and use its exact name.
Example fix
// before
SpannerIO.Read read = SpannerIO.read().withInstanceId("my-instance").withProjectId("my-project");
// after
SpannerIO.Read read = SpannerIO.read().withProjectId("my-project").withInstanceId("my-instance").withDatabaseId("my-database"); Defensive patterns
Strategy: validation
Validate before calling
if (databaseId == null || databaseId.isEmpty()) { throw new IllegalArgumentException("databaseId must be set before building the Spanner transform"); } Try / catch
try { SpannerIO.read().withProjectId(p).withInstanceId(i).withDatabaseId(db); } catch (IllegalArgumentException e) { log.error("Spanner config incomplete: {}", e.getMessage()); throw new ConfigException(e); } Prevention
- Validate projectId/instanceId/databaseId together in one pre-flight check before building transforms.
- Fail pipeline-option parsing early when required Spanner options are blank.
- Use Objects.requireNonNull plus isEmpty checks on all option getters.
When it happens
Trigger: Building a SpannerIO.Read/Write transform (or external transform via the registrar) with databaseId(""), leaving databaseId unset on the builder, or populating the configuration from a map/JSON/CLI option where the databaseId key is present but blank.
Common situations: Environment variable or template parameter for the Spanner database is unset and defaulted to ""; typos like setDatabaseId vs setDatabaseName; YAML/JSON pipeline configs where the database field was removed; programmatic pipelines that pass through user-supplied options without validation.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- instanceId can't be empty
- Both clientCertPath and clientCertKeyPath must be specified
- Query and table params are mutually exclusive. Set just one
- Schema can't be empty
- ChangeStreamName can't be empty
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/eaf47121c3b1814d.
Report an issue: GitHub.