{"record":{"id":"fa9f3f6408bd5002","repo":"risingwavelabs/risingwave","slug":"duplicate-vnode-request-vnode-prev-vn","errorCode":null,"errorMessage":"duplicate vnode {:?}. request vnode: {:?}, prev vnode: {:?}. pending request: {:?}, request: {:?}","messagePattern":"duplicate vnode (.+?)\\. request vnode: (.+?), prev vnode: (.+?)\\. pending request: (.+?), request: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/src/manager/sink_coordination/coordinator_worker.rs","lineNumber":104,"sourceCode":"\nimpl<R> AligningRequests<R> {\n    fn add_new_request(\n        &mut self,\n        handle_id: HandleId,\n        request: R,\n        vnode_bitmap: &Bitmap,\n    ) -> anyhow::Result<()>\n    where\n        R: Debug,\n    {\n        let committed_bitmap = self\n            .committed_bitmap\n            .get_or_insert_with(|| Bitmap::zeros(vnode_bitmap.len()));\n        assert_eq!(committed_bitmap.len(), vnode_bitmap.len());\n\n        let check_bitmap = (&*committed_bitmap) & vnode_bitmap;\n        if check_bitmap.count_ones() > 0 {\n            return Err(anyhow!(\n                \"duplicate vnode {:?}. request vnode: {:?}, prev vnode: {:?}. pending request: {:?}, request: {:?}\",\n                check_bitmap.iter_ones().collect_vec(),\n                vnode_bitmap,\n                committed_bitmap,\n                self.requests,\n                request\n            ));\n        }\n        *committed_bitmap |= vnode_bitmap;\n        self.requests.push(request);\n        assert!(self.handle_ids.insert(handle_id));\n        Ok(())\n    }\n\n    fn aligned(&self) -> bool {\n        self.committed_bitmap.as_ref().is_some_and(|b| b.all())\n    }\n}","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/manager/sink_coordination/coordinator_worker.rs#L86-L122","documentation":"Returned by `CoordinatorWorkerContext::add_new_request` when a sink coordinator request's vnode bitmap overlaps vnodes already covered by the committed bitmap for the current epoch. The overlap bits (`check_bitmap.count_ones() > 0`) mean two requests claim the same vnode, which would corrupt sink coordination state, so the request is rejected with a diagnostic dump.","triggerScenarios":"A sink coordinator worker re-sends a request for vnodes it already committed (e.g. retry after a lost/late ack), or two workers simultaneously claim the same vnode range for the same sink and epoch.","commonSituations":"Network retries duplicating coordinator requests; worker restart re-registering the same vnode distribution; a bug in vnode assignment (e.g. scaling events applying a stale distribution).","solutions":["Check whether the client/worker is retrying an already-acked request; make request submission idempotent by keying on request id/epoch.","Compare the `request vnode` vs `prev vnode` lists in the message to find the overlapping vnodes and trace which worker owns them.","Verify vnode assignment logic on scaling/parallelism changes so a distribution is applied exactly once.","If this is a stale duplicate, drop the newer request rather than re-registering."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// detect overlap before submitting a coordination request\nlet overlap = (&committed_bitmap) & &vnode_bitmap;\nif overlap.count_ones() > 0 { return Err(anyhow!(\"request overlaps committed vnodes: {:?}\", overlap.iter_ones().collect_vec())); }","typeGuard":null,"tryCatchPattern":"match worker.add_new_request(request).await {\n    Err(e) if e.to_string().starts_with(\"duplicate vnode\") => {\n        // treat as duplicate: drop the request and wait for ack of the original\n    }\n    other => other?,\n}","preventionTips":["Make coordinator request submission idempotent (keyed by request id/epoch)","Avoid re-registering vnode distributions after worker restarts without clearing old state","Review vnode assignment on parallelism changes to guarantee single ownership"],"tags":["meta","sink","vnode","duplicate"],"backgroundTag":"invalid-state-transition","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}