diff --git a/Cargo.toml b/Cargo.toml
index d9b8790..8720e99 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,6 +19,9 @@ categories = ["asynchronous", "network-programming", "simulation"]
 [workspace]
 members = ["examples/*"]
 
+[workspace.package]
+rust-version = "1.83"
+
 [dependencies]
 bytes = "1.4"
 futures = "0.3"
diff --git a/src/dns.rs b/src/dns.rs
index 352a1e3..ff73921 100644
--- a/src/dns.rs
+++ b/src/dns.rs
@@ -63,7 +63,7 @@ impl ToIpAddr for String {
     }
 }
 
-impl<'a> ToIpAddr for &'a str {
+impl ToIpAddr for &'_ str {
     fn to_ip_addr(&self, dns: &mut Dns) -> IpAddr {
         if let Ok(ipaddr) = self.parse() {
             return ipaddr;
@@ -121,7 +121,7 @@ impl ToSocketAddrs for (String, u16) {
     }
 }
 
-impl<'a> ToSocketAddrs for (&'a str, u16) {
+impl ToSocketAddrs for (&'_ str, u16) {
     fn to_socket_addr(&self, dns: &Dns) -> SocketAddr {
         // When IP address is passed directly as a str.
         if let Ok(ip) = self.0.parse::<IpAddr>() {
diff --git a/src/sim.rs b/src/sim.rs
index 868550e..3cf6b8a 100644
--- a/src/sim.rs
+++ b/src/sim.rs
@@ -674,7 +674,7 @@ mod test {
         sim.client("client", async move {
             // Peers are partitioned. TCP setup should fail.
             let err = TcpStream::connect("server:1234").await.unwrap_err();
-            assert_eq!(err.kind(), io::ErrorKind::Other);
+            assert_eq!(err.kind(), io::ErrorKind::HostUnreachable);
             assert_eq!(err.to_string(), "host unreachable");
 
             Ok(())
diff --git a/src/top.rs b/src/top.rs
index f810112..98574a6 100644
--- a/src/top.rs
+++ b/src/top.rs
@@ -59,7 +59,7 @@ pub struct LinkIter<'a> {
     iter: std::collections::vec_deque::IterMut<'a, Sent>,
 }
 
-impl<'a> LinkIter<'a> {
+impl LinkIter<'_> {
     /// The [`IpAddr`] pair for the link. Always ordered to uniquely identify
     /// the link.
     pub fn pair(&self) -> (IpAddr, IpAddr) {
@@ -84,7 +84,7 @@ pub struct SentRef<'a> {
     sent: &'a mut Sent,
 }
 
-impl<'a> SentRef<'a> {
+impl SentRef<'_> {
     /// The (src, dst) [`SocketAddr`] pair for the message.
     pub fn pair(&self) -> (SocketAddr, SocketAddr) {
         (self.src, self.dst)
@@ -243,11 +243,7 @@ impl Topology {
             link.enqueue_message(&self.config, rand, src, dst, message);
             Ok(())
         } else {
-            // TODO: `ErrorKind::Other` is incorrect here, but
-            // `ErrorKind::HostUnreachable` has not been stabilized.
-            //
-            // See: https://github.com/rust-lang/rust/issues/86442
-            Err(Error::new(ErrorKind::Other, "host unreachable"))
+            Err(Error::new(ErrorKind::HostUnreachable, "host unreachable"))
         }
     }
 
diff --git a/tests/tcp.rs b/tests/tcp.rs
index 1238b58..e379aeb 100644
--- a/tests/tcp.rs
+++ b/tests/tcp.rs
@@ -45,7 +45,7 @@ fn network_partitions_during_connect() -> Result {
         turmoil::partition("client", "server");
 
         let err = TcpStream::connect(("server", PORT)).await.unwrap_err();
-        assert_eq!(err.kind(), io::ErrorKind::Other);
+        assert_eq!(err.kind(), io::ErrorKind::HostUnreachable);
         assert_eq!(err.to_string(), "host unreachable");
 
         turmoil::repair("client", "server");
@@ -220,7 +220,7 @@ fn network_partition_once_connected() -> Result {
         assert!(timeout(Duration::from_secs(1), s.read_u8()).await.is_err());
 
         let err = s.write_u8(1).await.unwrap_err();
-        assert_eq!(err.kind(), io::ErrorKind::Other);
+        assert_eq!(err.kind(), io::ErrorKind::HostUnreachable);
         assert_eq!(err.to_string(), "host unreachable");
 
         Ok(())
@@ -232,7 +232,7 @@ fn network_partition_once_connected() -> Result {
         turmoil::partition("server", "client");
 
         let err = s.write_u8(1).await.unwrap_err();
-        assert_eq!(err.kind(), io::ErrorKind::Other);
+        assert_eq!(err.kind(), io::ErrorKind::HostUnreachable);
         assert_eq!(err.to_string(), "host unreachable");
 
         Ok(())
@@ -1129,7 +1129,7 @@ fn socket_to_nonexistent_node() -> Result {
         );
 
         let err = sock.unwrap_err();
-        assert_eq!(err.kind(), io::ErrorKind::Other);
+        assert_eq!(err.kind(), io::ErrorKind::HostUnreachable);
         assert_eq!(err.to_string(), "host unreachable");
 
         Ok(())
diff --git a/tests/udp.rs b/tests/udp.rs
index 9a38311..9f2083a 100644
--- a/tests/udp.rs
+++ b/tests/udp.rs
@@ -235,7 +235,7 @@ fn network_partition() -> Result {
 
         let sock = bind().await?;
         let err = send_ping(&sock).await.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::Other);
+        assert_eq!(err.kind(), ErrorKind::HostUnreachable);
         assert_eq!(err.to_string(), "host unreachable");
 
         Ok(())
@@ -562,7 +562,7 @@ fn loopback_localhost_public_v4() -> Result {
         let bind_addr = SocketAddr::new(bind_addr.ip(), 0);
         let socket = UdpSocket::bind(bind_addr).await?;
         let err = socket.send_to(&expected, connect_addr).await.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::Other);
+        assert_eq!(err.kind(), ErrorKind::HostUnreachable);
         assert_eq!(err.to_string(), "host unreachable");
 
         Ok(())
@@ -614,7 +614,7 @@ fn loopback_localhost_public_v6() -> Result {
         let bind_addr = SocketAddr::new(bind_addr.ip(), 0);
         let socket = UdpSocket::bind(bind_addr).await?;
         let err = socket.send_to(&expected, connect_addr).await.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::Other);
+        assert_eq!(err.kind(), ErrorKind::HostUnreachable);
         assert_eq!(err.to_string(), "host unreachable");
 
         Ok(())
@@ -723,7 +723,7 @@ fn socket_to_nonexistent_node() -> Result {
         );
 
         let err = send.unwrap_err();
-        assert_eq!(err.kind(), ErrorKind::Other);
+        assert_eq!(err.kind(), ErrorKind::HostUnreachable);
         assert_eq!(err.to_string(), "host unreachable");
 
         Ok(())