apache/beam · error · IllegalArgumentException

Pubsub subscription is not in projects/

Error message

Pubsub subscription is not in projects/<project_id>/subscriptions/<subscription_name> format: {path}

What it means

PubsubIO.Read.fromPath requires the subscription path to match projects/<project_id>/subscriptions/<subscription_name>. If the v1beta1 legacy formats also fail and SUBSCRIPTION_REGEXP doesn't match, this IllegalArgumentException is thrown describing the expected format.

Solutions

  1. Use the fully qualified path: projects/YOUR_PROJECT/subscriptions/YOUR_SUBSCRIPTION.
  2. Verify you didn't pass a topic path to fromSubscription (use fromTopic for projects/.../topics/...).
  3. Prefer the typed helpers fromSubscription(String) which build the path for you from project and subscription id if available.

Example fix

// before
PubsubIO.readStrings().fromSubscription("my-subscription");
// after
PubsubIO.readStrings().fromSubscription("projects/my-project/subscriptions/my-subscription");
Defensive patterns

Strategy: validation

Validate before calling

static void checkSubscriptionPath(String path) {
  if (!path.matches("projects/[a-zA-Z0-9-_.~%+]+/subscriptions/[a-zA-Z0-9-_.~%+]+"))
    throw new IllegalArgumentException("Expected projects/<proj>/subscriptions/<name>: " + path);
}

Type guard

boolean isSubscriptionPath(String p) {
  return p != null && p.matches("projects/[^/]+/subscriptions/[^/]+");
}

Try / catch

try {
  return PubsubIO.readStrings().fromSubscription(sub);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("subscriptions/<subscription_name> format"))
    throw new ConfigException("Subscription path must be projects/<proj>/subscriptions/<name>, got: " + sub, e);
  throw e;
}

Prevention

When it happens

Trigger: Calling PubsubIO.read...().fromSubscription()/fromPath with a bare subscription name ("mysub"), a topic path (projects/p/topics/t), a path with extra segments, or wrong separators.

Common situations: Copy/pasting just the subscription name from the Cloud Console; swapping topic and subscription strings; constructing paths with a '/subscriptions/' misspelling.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

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

    public static PubsubSubscription fromPath(String path) {
      if (path.startsWith(SUBSCRIPTION_RANDOM_TEST_PREFIX)
          || path.startsWith(SUBSCRIPTION_STARTING_SIGNAL)) {
        return new PubsubSubscription(PubsubSubscription.Type.FAKE, "", path);
      }

      String projectName, subscriptionName;

      Matcher v1beta1Match = V1BETA1_SUBSCRIPTION_REGEXP.matcher(path);
      if (v1beta1Match.matches()) {
        LOG.warn(
            "Saw subscription in v1beta1 format. Subscriptions should be in the format "
                + "projects/<project_id>/subscriptions/<subscription_name>");
        projectName = v1beta1Match.group(1);
        subscriptionName = v1beta1Match.group(2);
      } else {
        Matcher match = SUBSCRIPTION_REGEXP.matcher(path);
        if (!match.matches()) {
          throw new IllegalArgumentException(
              "Pubsub subscription is not in "
                  + "projects/<project_id>/subscriptions/<subscription_name> format: "
                  + path);
        }
        projectName = match.group(1);
        subscriptionName = match.group(2);
      }

      projectName =
          checkArgumentNotNull(
              projectName, "Invalid path: project name must be non-null: %s", path);
      subscriptionName =
          checkArgumentNotNull(
              subscriptionName, "Invalid path: subscription name must be non-null: %s", path);

      validateProjectName(projectName);
      validatePubsubName(subscriptionName);
      return new PubsubSubscription(PubsubSubscription.Type.NORMAL, projectName, subscriptionName);

View on GitHub (pinned to 12126d8942)