{"record":{"id":"3344fdcfcaa53fc1","repo":"vectordotdev/vector","slug":"notconnected","errorCode":"NotConnected","errorMessage":"Can't set keepalive on connection that has not been accepted yet.","messagePattern":"Can't set keepalive on connection that has not been accepted yet\\.","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"lib/vector-core/src/tls/incoming.rs","lineNumber":294,"sourceCode":"            ),\n            None => StreamState::Accepted(MaybeTlsStream::Raw(stream)),\n        };\n        Self { state, peer_addr }\n    }\n\n    // Explicit handshake method\n    pub async fn handshake(&mut self) -> crate::tls::Result<()> {\n        if let StreamState::Accepting(fut) = &mut self.state {\n            let stream = fut.await?;\n            self.state = StreamState::Accepted(MaybeTlsStream::Tls(stream));\n        }\n\n        Ok(())\n    }\n\n    pub fn set_keepalive(&mut self, keepalive: TcpKeepaliveConfig) -> io::Result<()> {\n        let stream = self.get_ref().ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::NotConnected,\n                \"Can't set keepalive on connection that has not been accepted yet.\",\n            )\n        })?;\n\n        if let Some(time_secs) = keepalive.time_secs {\n            let config =\n                socket2::TcpKeepalive::new().with_time(std::time::Duration::from_secs(time_secs));\n\n            tcp::set_keepalive(stream, &config)?;\n        }\n\n        Ok(())\n    }\n\n    pub fn set_receive_buffer_bytes(&mut self, bytes: usize) -> std::io::Result<()> {\n        let stream = self.get_ref().ok_or_else(|| {\n            io::Error::new(","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/lib/vector-core/src/tls/incoming.rs#L276-L312","documentation":"Runtime `io::Error` (kind `NotConnected`) from `MaybeTlsIncomingStream::set_keepalive` in lib/vector-core/src/tls/incoming.rs. The stream wraps a state machine: with TLS enabled the connection starts in `StreamState::Accepting` (handshake future in flight) and `get_ref()` only returns the `TcpStream` once the handshake completes and state becomes `Accepted`. Calling `set_keepalive` before that yields this error.","triggerScenarios":"In a TCP source with TLS enabled, calling `stream.set_keepalive(...)` immediately after accept, before `stream.handshake().await` has completed (or before any read/write drove the handshake to completion). With plain TCP (no acceptor) the state is `Accepted` from construction, so the same code appears to work until TLS is configured.","commonSituations":"Sources that configure `keepalive_time_secs` per connection (e.g. socket sources adding keepalive in their connection setup) and only fail in TLS deployments; also hitting the `Closed` state after the connection was torn down.","solutions":["Await the handshake first: `stream.handshake().await?;` then `stream.set_keepalive(cfg)?`","Or defer setting keepalive until after the first successful read/write (which also completes the handshake)","Treat `ErrorKind::NotConnected` from this call as 'not yet accepted' — retry after the handshake rather than failing the connection"],"exampleFix":"// before\nlet mut stream = listener.accept().await?;\nstream.set_keepalive(keepalive)?; // fails under TLS\n\n// after\nlet mut stream = listener.accept().await?;\nstream.handshake().await?;\nstream.set_keepalive(keepalive)?;","handlingStrategy":"validation","validationCode":"// Only tune socket options once the TLS handshake is done\nstream.handshake().await?; // completes Accepting -> Accepted\nif stream.get_ref().is_some() {\n    stream.set_keepalive(keepalive)?;\n}","typeGuard":null,"tryCatchPattern":"match stream.set_keepalive(cfg) {\n    Err(e) if e.kind() == std::io::ErrorKind::NotConnected => {\n        // handshake still pending: drive I/O or await handshake(), then retry once\n    }\n    Err(e) => return Err(e.into()),\n    Ok(()) => {}\n}","preventionTips":["Always await handshake() before any socket-option call on MaybeTlsIncomingStream","Test socket-tuning code paths with TLS enabled, not just plain TCP","get_ref().is_some() tells you whether the underlying TcpStream is reachable yet"],"tags":["rust","tls","tcp","keepalive","socket-options","async"],"backgroundTag":"socket-not-connected","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}