risingwavelabs/risingwave · error · RpcError

unable to send first request of {}

Error message

unable to send first request of {}

What it means

BidiStreamHandle::initialize failed to queue the first request: the initial request_sender.send() failed because the receiver passed to init_stream_fn dropped before accepting it, typically because establishing the streaming RPC itself failed.

Source

Thrown at src/rpc_client/src/lib.rs:284

        }
    }

    pub async fn initialize<
        F: FnOnce(Receiver<REQ>) -> Fut,
        St: Stream<Item = Result<RSP>> + Send + Unpin + 'static,
        Fut: Future<Output = Result<St>> + Send,
        R: Into<REQ>,
    >(
        first_request: R,
        init_stream_fn: F,
    ) -> Result<(Self, RSP)> {
        let (request_sender, request_receiver) = channel(DEFAULT_BUFFER_SIZE);

        // Send initial request in case of the blocking receive call from creating streaming request
        request_sender
            .send(first_request.into())
            .await
            .map_err(|_err| anyhow!("unable to send first request of {}", type_name::<REQ>()))?;

        let mut response_stream = init_stream_fn(request_receiver).await?;

        let first_response = response_stream
            .next()
            .await
            .ok_or_else(|| anyhow!("get empty response from first request"))??;

        Ok((
            Self {
                request_sender: BidiStreamSender { tx: request_sender },
                response_stream: BidiStreamReceiver {
                    stream: response_stream.boxed().peekable(),
                },
            },
            first_response,
        ))
    }

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify the target service address and that the connector/meta service is running, then retry initialize.
  2. Inspect init_stream_fn's own error (returned as the inner error of subsequent failures) for the gRPC failure cause.
  3. Add a retry with backoff around stream initialization for transient unavailability.

Example fix

// before
request_sender.send(first_request.into()).await.map_err(|_err| anyhow!("unable to send first request of {}", type_name::<REQ>()))?;
// after (caller-level)
let handle = loop {
    match BidiStreamHandle::initialize(&client, first.clone()).await {
        Ok(h) => break h,
        Err(e) => { warn!("init failed: {e}"); sleep(Duration::from_secs(1)).await; }
    }
};
Defensive patterns

Strategy: retry

Validate before calling

// before initialize
assert!(service_reachable(connector_endpoint).await, "connector service must be reachable");

Try / catch

let handle = retry(BoundedBackoff::from_secs(1), || async {
    BidiStreamHandle::initialize(&client, first.clone()).await
}).await?;

Prevention

When it happens

Trigger: Calling BidiStreamHandle::initialize when init_stream_fn's underlying gRPC streaming call fails immediately (server unreachable, endpoint rejected), dropping the request receiver.

Common situations: Connector/meta service down or restarting; wrong service address/port configuration; auth or version rejection on the streaming method.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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