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
- Verify the subscription id via the catalog (SHOW SUBSCRIPTIONS) before fetching by id.
- Handle the not-found case: recreate the subscription if it was dropped.
- 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
- Resolve subscriptions by name each time instead of caching ids.
- Re-fetch the catalog after DDL that may drop subscriptions.
- Handle RecordNotFound semantics for shared objects that others may drop concurrently.
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
- database {} not found when resolving reschedule intent
- {0} id not found: {1}
- mv not found
- {object_type} not found: {name}
- table id {dependent_table_id} has been dropped
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/e08c0b429d40a0ce.
Report an issue: GitHub.