embassy-rs/embassy · error

ipv4 support not enabled

Error message

ipv4 support not enabled

What it means

`TcpClient::connect` (the `embedded_nal_async::TcpConnect` impl in embassy-net) converts a `core::net::SocketAddr` to the stack's wire `IpAddress`. When the remote address is IPv4 but the `ipv4` cargo feature is disabled, no arm exists to build the address and the code panics with "ipv4 support not enabled". It is a compile-time feature misconfiguration surfaced as a runtime panic.

Solutions

  1. Enable the `ipv4` feature on the embassy-net dependency in Cargo.toml.
  2. Alternatively, connect to an IPv6 address so the `ipv6` arm is used, if the target network supports it.
  3. Check the address at runtime before calling `connect` and return your own error for unsupported families.
  4. Verify the resolved feature set with `cargo tree -e features -p embassy-net` in case another crate's default features disabled it.

Example fix

// before
embassy-net = { version = "0.4", features = ["ipv6"] }
let conn = client.connect("192.168.1.10:8080".parse().unwrap()).await?; // panics
// after
embassy-net = { version = "0.4", features = ["ipv4"] }
let conn = client.connect("192.168.1.10:8080".parse().unwrap()).await?;
Defensive patterns

Strategy: validation

Validate before calling

// Check address family against enabled features before connecting:
fn addr_supported(remote: core::net::SocketAddr) -> bool {
    match remote.ip() {
        IpAddr::V4(_) => cfg!(feature = "ipv4"), // check via your own build cfg constants
        IpAddr::V6(_) => cfg!(feature = "ipv6"),
    }
}
// Usage: if !addr_supported(remote) { return Err(MyErr::UnsupportedFamily); }

Type guard

fn is_v4(remote: &core::net::SocketAddr) -> bool { matches!(remote, core::net::SocketAddr::V4(_)) }

Try / catch

// Connect in a wrapper that validates first; in firmware panics cannot be caught, so never call connect with an unsupported family:
match addr { SocketAddr::V4(_) if !CFG_IPV4 => Err(MyError::UnsupportedFamily), _ => client.connect(addr).await }

Prevention

When it happens

Trigger: Calling `TcpClient::connect` (via the embedded-nal-async trait) with a `SocketAddr::V4(...)` remote while embassy-net was built without `features = ["ipv4"]`.

Common situations: Embedded Rust projects that connect to a hard-coded IPv4 address (e.g. "192.168.1.10:8080") but enabled only the `ipv6` feature (or neither) in embassy-net's Cargo feature list; often after upgrading embassy-net or copying a config tuned for IPv6-only networks.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/9408cba966c21cf5. Report an issue: GitHub.

Appendix: source

Thrown at embassy-net/src/tcp.rs:1340

            self.socket_timeout = timeout;
        }
    }

    impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_nal_async::TcpConnect
        for TcpClient<'d, N, TX_SZ, RX_SZ>
    {
        type Error = Error;
        type Connection<'m>
            = TcpConnection<'m, 'd, N, TX_SZ, RX_SZ>
        where
            Self: 'm;

        async fn connect<'a>(&'a self, remote: core::net::SocketAddr) -> Result<Self::Connection<'a>, Self::Error> {
            let addr: crate::wire::IpAddress = match remote.ip() {
                #[cfg(feature = "ipv4")]
                IpAddr::V4(addr) => crate::wire::IpAddress::Ipv4(addr),
                #[cfg(not(feature = "ipv4"))]
                IpAddr::V4(_) => panic!("ipv4 support not enabled"),
                #[cfg(feature = "ipv6")]
                IpAddr::V6(addr) => crate::wire::IpAddress::Ipv6(addr),
                #[cfg(not(feature = "ipv6"))]
                IpAddr::V6(_) => panic!("ipv6 support not enabled"),
            };
            let remote_endpoint = (addr, remote.port());
            let mut socket = TcpConnection::new(self.stack, self.state)?;
            socket.socket.set_timeout(self.socket_timeout);
            socket
                .socket
                .connect(remote_endpoint)
                .await
                .map_err(|_| Error::ConnectionReset)?;
            Ok(socket)
        }
    }

    /// Opened TCP connection in a [`TcpClient`].

View on GitHub (pinned to 463a07b963)