apache/beam · error · IllegalArgumentException
MetadataDatabase can't be empty
Error message
MetadataDatabase can't be empty
What it means
Thrown by ChangeStreamReaderBuilder.build() when the metadataDatabase configuration is empty. The connector requires a database in the metadata instance to persist change-stream connector metadata; without it the built transform cannot run.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerTransformRegistrar.java:507
}
@Override
@NonNull
public PTransform<PBegin, PCollection<String>> buildExternal(
ChangeStreamReaderBuilder.Configuration configuration) {
configuration.checkMandatoryFields();
if (configuration.changeStreamName.isEmpty()) {
throw new IllegalArgumentException("ChangeStreamName can't be empty");
}
if (configuration.metadataInstance.isEmpty()) {
throw new IllegalArgumentException("MetadataInstance can't be empty");
}
if (configuration.metadataDatabase.isEmpty()) {
throw new IllegalArgumentException("MetadataDatabase can't be empty");
}
SpannerIO.ReadChangeStream readChangeStream =
SpannerIO.readChangeStream()
.withProjectId(configuration.projectId)
.withInstanceId(configuration.instanceId)
.withDatabaseId(configuration.databaseId)
.withChangeStreamName(configuration.changeStreamName)
.withMetadataInstance(configuration.metadataInstance)
.withMetadataDatabase(configuration.metadataDatabase);
if (configuration.inclusiveStartAt != null) {
readChangeStream = readChangeStream.withInclusiveStartAt(configuration.inclusiveStartAt);
}
if (configuration.inclusiveEndAt != null) {
readChangeStream = readChangeStream.withInclusiveEndAt(configuration.inclusiveEndAt);
}View on GitHub (pinned to 12126d8942)
Solutions
- Set withMetadataDatabase("your-database") (or populate the metadataDatabase option) with an existing Spanner database in the metadata instance.
- Create the metadata database if it does not exist, or point at the database that hosts the change stream.
- Add startup validation of the pipeline options to fail fast with a clear message.
Example fix
// before
.withMetadataInstance(metadataInstance)
.withMetadataDatabase("")
// after
.withMetadataInstance(metadataInstance)
.withMetadataDatabase("metadata-db") Defensive patterns
Strategy: validation
Validate before calling
// before building
if (metadataDatabase == null || metadataDatabase.isEmpty()) {
throw new IllegalArgumentException("metadataDatabase must be a non-empty Spanner database ID");
} Prevention
- Set withMetadataDatabase explicitly; never rely on an implicit default.
- Ensure the database exists in the metadata instance before launching the pipeline.
- Add a config-lint step in CI for pipeline option files.
When it happens
Trigger: Building a SpannerIO.ReadChangeStream transform with withMetadataDatabase("") omitted/left blank in the ChangeStreamReadConfiguration, then calling build().
Common situations: Pipeline options files missing the metadataDatabase key; users assuming the metadata database defaults to the source database but leaving the field empty; template parameters not bound at runtime.
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
- MetadataInstance can't be empty
- Unrecognized dialect: + dialect.name()
- Experimental host can only be used with instance id: + EXPER
- Failed to parse DirectedReadOptions from string: + directedR
- Start time cannot be after end time.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/004d70371b466595.
Report an issue: GitHub.