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

  1. Inspect the remote sink writer service implementation to ensure it always attaches metadata to Commit responses
  2. Verify client and service versions match the expected SinkWriterStreamResponse protocol
  3. 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

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


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