{"record":{"id":"d2bc088ddff120be","repo":"tokio-rs/tokio","slug":"datagram-cannot-be-called-on-a-stream-socket","errorCode":null,"errorMessage":"datagram cannot be called on a stream socket","messagePattern":"datagram cannot be called on a stream socket","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"tokio/src/net/unix/socket.rs","lineNumber":232,"sourceCode":"        }\n        let mio = {\n            use std::os::unix::io::{FromRawFd, IntoRawFd};\n\n            let raw_fd = self.inner.into_raw_fd();\n            unsafe { mio::net::UnixStream::from_raw_fd(raw_fd) }\n        };\n\n        UnixStream::connect_mio(mio).await\n    }\n\n    /// Converts the socket into a [`UnixDatagram`].\n    ///\n    /// Calling this function on a socket created by [`new_stream`] will return an error.\n    ///\n    /// [`new_stream`]: `UnixSocket::new_stream`\n    pub fn datagram(self) -> io::Result<UnixDatagram> {\n        if self.ty() == socket2::Type::STREAM {\n            return Err(io::Error::new(\n                io::ErrorKind::Other,\n                \"datagram cannot be called on a stream socket\",\n            ));\n        }\n        let mio = {\n            use std::os::unix::io::{FromRawFd, IntoRawFd};\n\n            let raw_fd = self.inner.into_raw_fd();\n            unsafe { mio::net::UnixDatagram::from_raw_fd(raw_fd) }\n        };\n\n        UnixDatagram::from_mio(mio)\n    }\n}\n\nimpl AsRawFd for UnixSocket {\n    fn as_raw_fd(&self) -> RawFd {\n        self.inner.as_raw_fd()","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/tokio-rs/tokio/blob/625954f365727668cb02d04172b34f1149637728/tokio/src/net/unix/socket.rs#L214-L250","documentation":"UnixSocket::datagram checks ty(); if it equals socket2::Type::STREAM, it returns io::ErrorKind::Other 'datagram cannot be called on a stream socket' before converting the fd into a UnixDatagram. A stream socket cannot be reinterpreted as a datagram socket, so tokio refuses. The doc notes this fires for new_stream-created sockets.","triggerScenarios":"Calling UnixSocket::datagram() on a socket created with UnixSocket::new_stream().","commonSituations":"Constructing a stream socket then trying to repurpose it as datagram; copy-paste across socket kinds; an abstraction that picks the wrong conversion method.","solutions":["If you need a UnixDatagram, construct with UnixSocket::new_datagram() and then call .datagram().","Keep stream and datagram code paths separate so the conversion matches the construction.","Add a type assertion (check ty() == Type::DGRAM) before calling .datagram() to fail with intent.","Review the abstraction layer that wraps UnixSocket to ensure it routes by socket type."],"exampleFix":"// before\nlet s = UnixSocket::new_stream()?;\nlet dg = s.datagram()?; // 'datagram cannot be called on a stream socket'\n\n// after\nlet s = UnixSocket::new_datagram()?;\ns.bind(path)?;\nlet dg = s.datagram()?;","handlingStrategy":"type-guard","validationCode":"let s = UnixSocket::new_datagram()?; // for datagram conversion\n// If you have an existing fd, assert socket2::Type::DGRAM before .datagram().","typeGuard":"fn is_datagram_on_stream(e: &io::Error) -> bool {\n    e.kind() == io::ErrorKind::Other\n        && e.to_string() == \"datagram cannot be called on a stream socket\"\n}","tryCatchPattern":"match sock.datagram() {\n    Ok(d) => Ok(d),\n    Err(e) if e.to_string() == \"datagram cannot be called on a stream socket\" => {\n        Err(anyhow::anyhow!(\"use new_datagram() to obtain a UnixDatagram\"))\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["Construct with new_datagram() before calling .datagram().","Keep stream and datagram code paths separate so conversion matches construction.","Assert ty() == Type::DGRAM before calling .datagram() to fail with intent.","Review wrapper abstractions to ensure they route by socket type."],"tags":["unix","socket","datagram","stream","tokio"],"backgroundTag":null,"analyzedSha":"625954f365727668cb02d04172b34f1149637728","analyzedAt":"2026-08-11T17:46:45.378Z","contentChangedAt":"2026-08-11T17:46:45.378Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}