{"record":{"id":"802bbe54a7e0e4d2","repo":"risingwavelabs/risingwave","slug":"should-get-start-epoch-after-update-vnode-bitmap","errorCode":null,"errorMessage":"should get start epoch after update vnode bitmap","messagePattern":"should get start epoch after update vnode bitmap","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/rpc_client/src/sink_coordinate_client.rs","lineNumber":134,"sourceCode":"    }\n\n    pub async fn update_vnode_bitmap(&mut self, vnode_bitmap: &Bitmap) -> anyhow::Result<u64> {\n        self.send_request(CoordinateRequest {\n            msg: Some(coordinate_request::Msg::UpdateVnodeRequest(\n                UpdateVnodeBitmapRequest {\n                    vnode_bitmap: Some(vnode_bitmap.to_protobuf()),\n                },\n            )),\n        })\n        .await?;\n        match self.next_response().await? {\n            CoordinateResponse {\n                msg:\n                    Some(coordinate_response::Msg::StartResponse(StartCoordinationResponse {\n                        log_store_rewind_start_epoch,\n                    })),\n            } => Ok(log_store_rewind_start_epoch\n                .ok_or_else(|| anyhow!(\"should get start epoch after update vnode bitmap\"))?),\n            msg => Err(anyhow!(\"should get start response but get {:?}\", msg)),\n        }\n    }\n\n    pub async fn stop(mut self) -> anyhow::Result<()> {\n        self.send_request(CoordinateRequest {\n            msg: Some(coordinate_request::Msg::Stop(true)),\n        })\n        .await?;\n        match self.next_response().await? {\n            CoordinateResponse {\n                msg: Some(coordinate_response::Msg::Stopped(_)),\n            } => Ok(()),\n            msg => Err(anyhow!(\"should get Stopped but get {:?}\", msg)),\n        }\n    }\n\n    pub async fn align_initial_epoch(&mut self, initial_epoch: u64) -> anyhow::Result<u64> {","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/rpc_client/src/sink_coordinate_client.rs#L116-L152","documentation":"SinkCoordinateClient::update_vnode_bitmap sends an UpdateVnodeRequest and expects a StartResponse carrying a log_store_rewind_start_epoch. If that inner epoch field is None, the client errors: the coordinator acknowledged but did not supply the required start epoch needed to continue.","triggerScenarios":"Calling update_vnode_bitmap and the coordinator returns StartResponse with `log_store_rewind_start_epoch` unset (None) — coordinator bug or version skew omitting the field.","commonSituations":"Newer compute node against older coordinator that doesn't set the field; coordinator logic bug after fragment rescheduling; corrupted response.","solutions":["Verify compute node and meta/coordinator versions match; upgrade if skewed","Retry the update_vnode_bitmap call after re-establishing the coordination stream","Inspect coordinator logs; file a bug if StartResponse consistently omits the epoch"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rust\nlet epoch = match client.update_vnode_bitmap(&bitmap).await {\n    Ok(e) => e,\n    Err(e) if e.to_string().contains(\"start epoch\") => {\n        tracing::warn!(\"missing start epoch: {e:#}; retrying with fresh stream\");\n        let mut c = rebuild_sink_coordinate_client().await?;\n        c.update_vnode_bitmap(&bitmap).await?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Keep compute node and meta on the same version","Retry the bitmap update after stream rebuild on version-skew errors","Watch coordinator logs during fragment rescheduling"],"tags":["grpc","protocol","sink","protobuf"],"backgroundTag":"unexpected-api-response-shape","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"}