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
- Use the fully qualified path: projects/YOUR_PROJECT/subscriptions/YOUR_SUBSCRIPTION.
- Verify you didn't pass a topic path to fromSubscription (use fromTopic for projects/.../topics/...).
- 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
- Always store the fully qualified path, not the short name
- Build paths with String.format("projects/%s/subscriptions/%s", proj, name)
- Double-check topic vs subscription config keys
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
- Pubsub topic is not in projects/
- Can't set both the topic and the subscription for a…
- Cannot get data catalog name for malformed topic path
- Could not parse Pub/Sub message
- Illegal Pubsub object name specified
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)