risingwavelabs/risingwave · error · SinkError::Remote
get none metadata in commit response for coordinated sink wr
Error message
get none metadata in commit response for coordinated sink writer
What it means
During a checkpoint barrier, `RemoteSinkWriter::barrier` calls `stream_handle.commit(epoch)` on the coordinated sink writer service and expects the commit response to carry sink metadata. If the response has `metadata: None`, this error is thrown because the coordinator contract requires metadata on commit.
Source
Thrown at src/connector/src/sink/remote.rs:662
self.batch_id += 1;
Ok(())
}
async fn begin_epoch(&mut self, epoch: u64) -> Result<()> {
self.epoch = Some(epoch);
Ok(())
}
async fn barrier(&mut self, is_checkpoint: bool) -> Result<Option<SinkMetadata>> {
let epoch = self.epoch.ok_or_else(|| {
SinkError::Remote(anyhow!("epoch has not been initialize, call `begin_epoch`"))
})?;
if is_checkpoint {
// TODO: add metrics to measure commit time
let rsp = self.stream_handle.commit(epoch).await?;
rsp.metadata
.ok_or_else(|| {
SinkError::Remote(anyhow!(
"get none metadata in commit response for coordinated sink writer"
))
})
.map(Some)
} else {
self.stream_handle.barrier(epoch).await?;
Ok(None)
}
}
}
pub struct RemoteCoordinator {
stream_handle: SinkCoordinatorStreamHandle,
}
impl RemoteCoordinator {
pub async fn new<R: RemoteSinkTrait>(param: SinkParam) -> Result<Self> {
let stream_handle = EmbeddedConnectorClient::new()?View on GitHub (pinned to 6469eb736d)
Solutions
- Inspect the remote sink writer service implementation to ensure it always attaches metadata to Commit responses
- Verify client and service versions match the expected SinkWriterStreamResponse protocol
- Log the raw commit response to identify which writer/service returns None metadata
Example fix
// before (service side)
Ok(SinkWriterStreamResponse { response: Some(Response::Commit(SinkWriterCommitResponse { metadata: None })) })
// after
Ok(SinkWriterStreamResponse { response: Some(Response::Commit(SinkWriterCommitResponse { metadata: Some(metadata) })) }) Defensive patterns
Strategy: try-catch
Validate before calling
// before committing, verify the service implementation returns metadata assert!(commit_response.metadata.is_some(), "coordinated sink must return commit metadata");
Type guard
fn has_metadata(rsp: &SinkWriterStreamResponse) -> bool {
matches!(&rsp.response, Some(Response::Commit(c)) if c.metadata.is_some())
} Try / catch
match writer.barrier(true).await {
Ok(_) => {},
Err(e) if e.to_string().contains("get none metadata") => log::error!("sink service returned empty commit metadata: {}", e),
Err(e) => return Err(e),
} Prevention
- Keep client and sink service protobuf definitions in lockstep
- Write contract tests asserting Commit responses always carry metadata
- Version-gate coordinated sink deployments
When it happens
Trigger: A checkpoint commit against a coordinated (distributed) sink writer whose `SinkWriterStreamResponse::Commit` reply contains no metadata — e.g. the remote writer implementation returned an empty commit response.
Common situations: Custom or buggy sink implementations behind the coordinated writer service; version mismatches between frontend/stream and the sink service; serialization dropping the metadata field.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- should get start response but get {:?}
- should have meta client
- should get metadata on checkpoint barrier
- newly start epoch {} after update vnode bitmap not matched w
- Time went backwards
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/bb28feca5841a6a0.
Report an issue: GitHub.