apache/beam · error · IllegalArgumentException

To read from Pubsub, a subscription name or a topic name mus

Error message

To read from Pubsub, a subscription name or a topic name must be provided. Not both.

What it means

PubsubReadSchemaTransformProvider.from() requires the read configuration to specify exactly one of a Pubsub subscription name or a topic name. It throws when both are set, because reading via both a subscription and a topic is ambiguous — a topic read creates its own subscription semantics, which conflicts with an explicit subscription.

Source

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

  public static final TupleTag<Row> OUTPUT_TAG = new TupleTag<Row>() {};
  public static final TupleTag<Row> ERROR_TAG = new TupleTag<Row>() {};
  public static final Schema ERROR_SCHEMA =
      Schema.builder().addStringField("error").addNullableByteArrayField("row").build();

  @Override
  public Class<PubsubReadSchemaTransformConfiguration> configurationClass() {
    return PubsubReadSchemaTransformConfiguration.class;
  }

  @Override
  public SchemaTransform from(PubsubReadSchemaTransformConfiguration configuration) {
    if (configuration.getSubscription() == null && configuration.getTopic() == null) {
      throw new IllegalArgumentException(
          "To read from Pubsub, a subscription name or a topic name must be provided");
    }

    if (configuration.getSubscription() != null && configuration.getTopic() != null) {
      throw new IllegalArgumentException(
          "To read from Pubsub, a subscription name or a topic name must be provided. Not both.");
    }

    if (!"RAW".equals(configuration.getFormat())) {
      if ((Strings.isNullOrEmpty(configuration.getSchema())
              && !Strings.isNullOrEmpty(configuration.getFormat()))
          || (!Strings.isNullOrEmpty(configuration.getSchema())
              && Strings.isNullOrEmpty(configuration.getFormat()))) {
        throw new IllegalArgumentException(
            "A schema was provided without a data format (or viceversa). Please provide "
                + "both of these parameters to read from Pubsub, or if you would like to use the Pubsub schema service,"
                + " please leave both of these blank.");
      }
    }

    Schema payloadSchema;
    SerializableFunction<byte[], Row> payloadMapper;

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove one of the two values from the configuration Row — set exactly one of 'subscription' or 'topic'.
  2. If consuming an existing subscription, clear 'topic' and keep 'subscription'.
  3. If reading from a topic without an existing subscription, clear 'subscription' and keep 'topic'.
  4. Validate the merged config before building the transform to ensure the two fields are not both set.

Example fix

// before
config = Config.builder().setTopic("projects/p/topics/t").setSubscription("projects/p/subs/s").build();
// after
config = Config.builder().setSubscription("projects/p/subs/s").build(); // or setTopic only
Defensive patterns

Strategy: validation

Validate before calling

if ((cfg.getSubscription() != null) == (cfg.getTopic() != null)) { throw new IllegalArgumentException("Provide exactly one of subscription or topic"); }

Try / catch

try { return provider.from(cfg); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Not both")) { /* fix config: clear one field */ } throw e; }

Prevention

When it happens

Trigger: Calling PubsubReadSchemaTransformProvider.from(configurationRow) where the configuration Row has BOTH the 'subscription' and 'topic' fields populated with non-null values.

Common situations: Config files or pipeline templates that merge defaults (topic from one place, subscription from another); users who think they must supply both; programmatic config building that copies both fields from a template.

Related errors


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