vectordotdev/vector · error
Can't set keepalive on connection that has not been…
Error message
Can't set keepalive on connection that has not been accepted yet.
What it means
`IncomingTlsListener::set_keepalive` needs a reference to the accepted TCP stream. The wrapper holds `Option<T>` and returns `Err(NotConnected)` when called before a connection has been accepted and stored, since there is no socket on which to apply the keepalive options.
Solutions
- Apply keepalive only after the connection has been accepted (call it inside handle_stream / after awaiting accept).
- Check that the wrapper was created from an accepted stream, not a fresh listener.
- Set keepalive via TcpKeepaliveConfig so it is applied post-accept automatically.
Example fix
// before let mut conn = listener.accept().await?; // not yet polled to completion conn.set_keepalive(cfg)?; // after let mut conn = listener.accept().await?.into_stream(); conn.set_keepalive(cfg).await?; // after connection exists
Defensive patterns
Strategy: try-catch
Validate before calling
if conn.get_ref().is_none() {
return Err(std::io::Error::new(std::io::ErrorKind::NotConnected, "connection not accepted yet"));
} Type guard
// Rust: match on the Option inside the wrapper
fn is_accepted(conn: &IncomingConnection) -> bool { conn.get_ref().is_some() } Try / catch
match conn.set_keepalive(cfg) {
Err(e) if e.kind() == std::io::ErrorKind::NotConnected => {
// defer or skip; connection not yet accepted
}
other => other?,
} Prevention
- Always await accept before tuning socket options.
- Apply keepalive/buffer settings inside the same task that accepts the connection.
When it happens
Trigger: Calling `set_keepalive` on the listener's connection wrapper before the accept future completes / before `handle_stream` has stored the accepted stream.
Common situations: Configuring TCP keepalive from a different task than the one that awaits the accept, or racing accept and socket tuning; usually surfaces as NotConnected on a TLS listener wrapper.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Can't set receive buffer size on connection that has not…
- NotConnected
- Pong timeout
- BrokenPipe
- Building HTTP client failed
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/25707aea3cf4b50b.
Report an issue: GitHub.
Appendix: source
Thrown at lib/vector-core/src/tls/incoming.rs:314
),
None => StreamState::Accepted(MaybeTlsStream::Raw(stream)),
};
Self { state, peer_addr }
}
// Explicit handshake method
pub async fn handshake(&mut self) -> crate::tls::Result<()> {
if let StreamState::Accepting(fut) = &mut self.state {
let stream = fut.await?;
self.state = StreamState::Accepted(MaybeTlsStream::Tls(stream));
}
Ok(())
}
pub fn set_keepalive(&mut self, keepalive: TcpKeepaliveConfig) -> io::Result<()> {
let stream = self.get_ref().ok_or_else(|| {
io::Error::new(
io::ErrorKind::NotConnected,
"Can't set keepalive on connection that has not been accepted yet.",
)
})?;
if let Some(time_secs) = keepalive.time_secs {
let config =
socket2::TcpKeepalive::new().with_time(std::time::Duration::from_secs(time_secs));
tcp::set_keepalive(stream, &config)?;
}
Ok(())
}
pub fn set_receive_buffer_bytes(&mut self, bytes: usize) -> std::io::Result<()> {
let stream = self.get_ref().ok_or_else(|| {
io::Error::new(View on GitHub (pinned to bdb87aeaa4)