risingwavelabs/risingwave · critical

Some streaming jobs already exist in meta, please start…

Error message

Some streaming jobs already exist in meta, please start with recovery enabled or clean up the metadata using `./risedev clean-data`

What it means

At startup, the barrier manager checks whether the metadata store already contains streaming jobs. If `has_any_streaming_jobs()` is true while recovery is disabled, it panics with a message telling the operator to either start with recovery enabled or clean the metadata, because leftover streaming jobs cannot run without a recovery-capable barrier manager.

Solutions

  1. Enable recovery in the config (recovery mode / recovery-enabled) and restart, so existing jobs are recovered.
  2. If the data is disposable, run `./risedev clean-data` (or wipe the meta/state store) and start fresh.
  3. Do NOT try to disable streaming or bypass the check; the panic is intentional to prevent silent data inconsistency.

Example fix

// before: starting with recovery disabled on a dirty store
start_node(recovery_enabled: false) // panics
// after (risedev)
// ./risedev clean-data && ./risedev d
// or in config: [meta]
// enable_recovery = true
Defensive patterns

Strategy: validation

Validate before calling

# before starting with recovery disabled, ensure the store is clean
./risedev clean-data
# or verify no jobs exist first
psql -c "SELECT count(*) FROM rw_streaming_jobs;"

Prevention

When it happens

Trigger: Starting the meta node with recovery disabled (e.g. a config/profile where state store or recovery is off) against a metadata store that retains streaming jobs from a previous run — the panic occurs during `run` (invoked from `start`) before serving traffic.

Common situations: Reusing a persistent metadata directory ( Hummock/meta state) after a previous run with jobs; switching a dev profile from recovery-enabled to recovery-disabled; forgetting `./risedev clean-data` between experiments.

Related errors


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

Appendix: source

Thrown at src/meta/src/barrier/worker.rs:381

    /// Start an infinite loop to take scheduled barriers and send them.
    async fn run(mut self, shutdown_rx: Receiver<()>) {
        tracing::info!(
            "Starting barrier manager with: enable_recovery={}, in_flight_barrier_nums={}",
            self.enable_recovery,
            self.checkpoint_control.in_flight_barrier_nums,
        );

        if !self.enable_recovery {
            let job_exist = self
                .context
                .metadata_manager
                .catalog_controller
                .has_any_streaming_jobs()
                .await
                .unwrap();
            if job_exist {
                panic!(
                    "Some streaming jobs already exist in meta, please start with recovery enabled \
                or clean up the metadata using `./risedev clean-data`"
                );
            }
        }

        {
            // Bootstrap recovery. Here we simply trigger a recovery process to achieve the
            // consistency.
            // Even if there's no actor to recover, we still go through the recovery process to
            // inject the first `Initial` barrier.
            let span = tracing::info_span!("bootstrap_recovery");
            crate::telemetry::report_event(
                risingwave_pb::telemetry::TelemetryEventStage::Recovery,
                "normal_recovery",
                0,
                None,
                None,

View on GitHub (pinned to 6469eb736d)