risingwavelabs/risingwave · error · anyhow::Error

expect InitResponse but get

Error message

expect InitResponse but get {:?}

What it means

StreamClient::start_streaming_control opens a streaming control stream and expects the very first StreamingControlStreamResponse to be an Init response. Anything else means the stream engine did not initialize the control stream correctly, so the client refuses to hand back the control handle.

Solutions

  1. Check the target compute node's logs for stream-creation errors around this time
  2. Verify all components run the same RisingWave version; restart mismatched nodes
  3. Retry start_streaming_control; if persistent, check node health and connectivity (proxies, load balancers)
Defensive patterns

Strategy: retry

Try / catch

// Rust
match stream_client.start_streaming_control(...).await {
    Ok(handle) => handle,
    Err(e) if e.to_string().contains("expect InitResponse") => {
        tracing::warn!("control stream not initialized: {e:#}; retrying");
        stream_client.start_streaming_control(...).await?
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling start_streaming_control when the first response from the compute node is not Response::Init — e.g. the server pushed an error/completion message first, stream engine is unhealthy, or component versions are skewed.

Common situations: Compute node crashed or is shutting down while the client connects; version mismatch between frontend/meta and stream engine; network proxy mangling the gRPC stream; stale stream reused from a failed actor.

Related errors


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

Appendix: source

Thrown at src/rpc_client/src/stream_client.rs:109

                init_request,
            )),
        };
        let mut client = self.0.clone();
        let (handle, first_rsp) =
            UnboundedBidiStreamHandle::initialize(first_request, |rx| async move {
                client
                    .streaming_control_stream(UnboundedReceiverStream::new(rx))
                    .await
                    .map(|response| response.into_inner().map_err(RpcError::from_stream_status))
                    .map_err(RpcError::from_stream_status)
            })
            .await?;
        match first_rsp {
            StreamingControlStreamResponse {
                response: Some(streaming_control_stream_response::Response::Init(InitResponse {})),
            } => {}
            other => {
                return Err(anyhow!("expect InitResponse but get {:?}", other).into());
            }
        };
        Ok(handle)
    }
}

View on GitHub (pinned to 6469eb736d)