risingwavelabs/risingwave · error

cannot find subscription with id {}

Error message

cannot find subscription with id {}

What it means

get_subscription_by_id looks up subscription catalog objects by id, maps them to PbSubscription models, and uses find_or_first(|_| true) to select the match. When the filtered iterator is empty (no subscription row/object exists for the given id), the ok_or_else on the resulting Option produces this anyhow error. It simply means no subscription with the requested id exists in the catalog.

Source

Thrown at src/meta/src/controller/catalog/get_op.rs:342

            })
            .collect())
    }

    pub async fn get_subscription_by_id(
        &self,
        subscription_id: SubscriptionId,
    ) -> MetaResult<PbSubscription> {
        let inner = self.inner.read().await;
        let subscription_objs = Subscription::find()
            .find_also_related(Object)
            .filter(subscription::Column::SubscriptionId.eq(subscription_id))
            .all(&inner.db)
            .await?;
        let subscription: PbSubscription = subscription_objs
            .into_iter()
            .map(|(subscription, obj)| ObjectModel(subscription, obj.unwrap(), None).into())
            .find_or_first(|_| true)
            .ok_or_else(|| anyhow!("cannot find subscription with id {}", subscription_id))?;

        Ok(subscription)
    }

    pub async fn get_mv_depended_subscriptions(
        &self,
        database_id: Option<DatabaseId>,
    ) -> MetaResult<HashMap<TableId, HashMap<SubscriptionId, u64>>> {
        let inner = self.inner.read().await;
        let select = Subscription::find()
            .select_only()
            .select_column(subscription::Column::SubscriptionId)
            .select_column(subscription::Column::DependentTableId)
            .select_column(subscription::Column::RetentionSeconds);
        let select = if let Some(database_id) = database_id {
            select
                .join(JoinType::InnerJoin, subscription::Relation::Object.def())
                .filter(object::Column::DatabaseId.eq(database_id))

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify the subscription id via the catalog (SHOW SUBSCRIPTIONS) before fetching by id.
  2. Handle the not-found case: recreate the subscription if it was dropped.
  3. Use the subscription name lookup instead of a cached id.

Example fix

// before
let sub = controller.get_subscription_by_id(stale_id).await?;
// after
match controller.get_subscription_by_id(id).await {
    Ok(sub) => sub,
    Err(e) if e.to_string().contains("cannot find subscription") => recreate_subscription(),
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust
async fn subscription_exists(controller: &CatalogController, id: u32) -> bool {
    controller.list_subscriptions().await.map(|subs| subs.iter().any(|s| s.id == id)).unwrap_or(false)
}

Try / catch

match controller.get_subscription_by_id(id).await {
    Ok(sub) => sub,
    Err(e) if e.to_string().contains("cannot find subscription with id") => {
        // treat as RecordNotFound: refresh catalog or recreate
        refresh_and_recreate(id)
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling get_subscription_by_id (e.g. via SHOW/META internal RPC) with a subscription_id that does not exist, or one that was already dropped in another session/transaction.

Common situations: Consumers holding stale subscription ids after the subscription was dropped; racing DDL where a subscription is removed while a client queries it; typos or id reuse assumptions in tooling.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/e08c0b429d40a0ce. Report an issue: GitHub.