{"record":{"id":"6f27c5a4e17c6f90","repo":"risingwavelabs/risingwave","slug":"expect-aligninitialepoch-but-got","errorCode":null,"errorMessage":"expect AlignInitialEpoch but got {}","messagePattern":"expect AlignInitialEpoch but got (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/meta/src/manager/sink_coordination/coordinator_worker.rs","lineNumber":630,"sourceCode":"        pending_handle_ids: impl IntoIterator<Item = HandleId>,\n    ) -> anyhow::Result<()> {\n        let log_store_rewind_start_epoch = self.last_writer_acked_epoch;\n        self.handle_manager\n            .start(log_store_rewind_start_epoch, pending_handle_ids)?;\n        if log_store_rewind_start_epoch.is_none() {\n            let mut align_requests = AligningRequests::default();\n            while !align_requests.aligned() {\n                let (handle_id, event) = self.handle_manager.next_event().await?;\n                match event {\n                    CoordinationHandleManagerEvent::AlignInitialEpoch(initial_epoch) => {\n                        align_requests.add_new_request(\n                            handle_id,\n                            initial_epoch,\n                            self.handle_manager.vnode_bitmap(handle_id),\n                        )?;\n                    }\n                    other => {\n                        return Err(anyhow!(\"expect AlignInitialEpoch but got {}\", other.name()));\n                    }\n                }\n            }\n            let aligned_initial_epoch = align_requests\n                .requests\n                .into_iter()\n                .max()\n                .expect(\"non-empty\");\n            self.handle_manager\n                .ack_aligned_initial_epoch(aligned_initial_epoch)?;\n        }\n        Ok(())\n    }\n\n    async fn next_event(\n        &mut self,\n        two_phase_handler: &mut TwoPhaseCommitHandler,\n    ) -> anyhow::Result<CoordinatorWorkerEvent> {","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/manager/sink_coordination/coordinator_worker.rs#L612-L648","documentation":"`handle_init_requests_impl` collects initial epoch alignment requests from newly registered handles and expects each to be `AlignInitialEpoch`. Any other event type breaks the init protocol and returns this error. It indicates a handle is sending commits or stops during the alignment collection window.","triggerScenarios":"While draining init requests for a batch of new handles, one handle emits `CommitRequest`, `Stop`, or `NewHandle` instead of `AlignInitialEpoch` — e.g. a writer that skips alignment, aborts, or double-registers during `try_handle_init_requests`.","commonSituations":"Mixed writer versions where some do not participate in initial epoch alignment; a writer failing right as the coordinator collects init requests; a race where the same HandleId re-registers mid-batch.","solutions":["Read the event name in the message to identify the offending writer behavior and fix that writer to align first.","Ensure all sink writers are upgraded to a version supporting the AlignInitialEpoch handshake.","Handle Stop events during init batch collection gracefully (drop the handle) rather than failing the entire batch.","Add trace logs around `try_handle_init_requests` to capture which handle sent the unexpected event."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// writer-side: ensure AlignInitialEpoch is the first event after StartResponse when alignment is requested\nif self.requires_alignment && !self.aligned { align_before_commit()?; }","typeGuard":"fn is_align_initial_epoch(ev: &CoordinationHandleManagerEvent) -> bool { matches!(ev, CoordinationHandleManagerEvent::AlignInitialEpoch(_)) }","tryCatchPattern":"// coordinator: catch and identify the straggler handle from logs, then restart the batch\nErr(e) if e.to_string().contains(\"expect AlignInitialEpoch\") => restart_init_batch(),","preventionTips":["Upgrade all writers to versions that implement the alignment handshake.","Treat writer Stop during init batch collection as a normal drop, not a batch failure.","Trace init batches to spot handles that skip alignment."],"tags":["rust","sink-coordination","protocol-state-machine"],"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-23T08:17:48.524Z"}