apache/beam · error · InvalidConfigurationException

Dead letter queue topic name is not specified

Error message

Dead letter queue topic name is not specified

What it means

PubsubSchemaIOProvider.validateDlq() accepts a deadLetterQueue topic name that may be null (feature disabled) but rejects the empty string. An empty DLQ topic name is not a valid Pubsub topic, so an InvalidConfigurationException is thrown.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/pubsub/PubsubSchemaIOProvider.java:172

  }

  private void validateDataSchema(@Nullable Schema schema) {
    if (schema == null) {
      throw new InvalidSchemaException(
          "Unsupported schema specified for Pubsub source in CREATE TABLE."
              + "CREATE TABLE for Pubsub topic must not be null");
    }
    if (!PubsubSchemaIO.fieldPresent(schema, TIMESTAMP_FIELD, FieldType.DATETIME)) {
      throw new InvalidSchemaException(
          "Unsupported schema specified for Pubsub source in CREATE TABLE."
              + "CREATE TABLE for Pubsub topic must include at least 'event_timestamp' field of "
              + "type 'TIMESTAMP'");
    }
  }

  private void validateDlq(@Nullable String deadLetterQueue) {
    if (deadLetterQueue != null && deadLetterQueue.isEmpty()) {
      throw new InvalidConfigurationException("Dead letter queue topic name is not specified");
    }
  }

  private void validateConfigurationSchema(Row configuration) {
    if (!configuration.getSchema().equals(configurationSchema())) {
      throw new InvalidConfigurationException(
          "Configuration schema provided does not match expected");
    }
  }

  /** An abstraction to create schema aware IOs. */
  private static class PubsubSchemaIO implements SchemaIO, Serializable {
    protected final Schema dataSchema;
    protected final String location;
    protected final boolean useFlatSchema;
    protected final Config config;

    private PubsubSchemaIO(String location, Row config, Schema dataSchema) {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Provide a full DLQ topic name (e.g. 'projects/my-project/topics/my-dlq') in the deadLetterQueue property.
  2. Or remove the deadLetterQueue property entirely to disable the dead letter queue.
  3. Fix the upstream template/env resolution so unset DLQ values become null/absent rather than "".

Example fix

-- before
... WITH OPTIONS ('deadLetterQueue' = '')
-- after
... WITH OPTIONS ('deadLetterQueue' = 'projects/my-project/topics/my-dlq')
Defensive patterns

Strategy: validation

Validate before calling

if (dlq != null && dlq.isEmpty()) { throw new IllegalArgumentException("deadLetterQueue must be a full topic name or omitted entirely"); }

Try / catch

try { ioProvider.from(tableConfig); } catch (InvalidConfigurationException e) { if (e.getMessage().contains("Dead letter queue")) { /* set a real DLQ topic or drop the option */ } throw e; }

Prevention

When it happens

Trigger: Providing the 'deadLetterQueue' table property as an empty string (e.g. deadLetterQueue='' in WITH OPTIONS, or an unset template variable rendering as ""), so deadLetterQueue != null && deadLetterQueue.isEmpty() is true.

Common situations: Template/env variable for the DLQ topic resolving to an empty string; UIs or config generators emitting deadLetterQueue='' instead of omitting the key; copy-paste where the topic path was deleted but the key kept.

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/862cc56dbf0cc230. Report an issue: GitHub.