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

  1. Set withMetadataDatabase("your-database") (or populate the metadataDatabase option) with an existing Spanner database in the metadata instance.
  2. Create the metadata database if it does not exist, or point at the database that hosts the change stream.
  3. 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

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


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