hatoo/oha · error

couldn't bind to address

Error message

couldn't bind to address

What it means

quic_endpoint fails when quinn::Endpoint::bind cannot bind a local UDP socket for the QUIC/HTTP-3 connection (IPv4 or IPv6 per the is_ipv6 flag). Typical causes: the OS denied the bind (firewall/SELinux), no interface supports the requested address family, or the port/address is otherwise unavailable. It propagates out of quic_client.

Solutions

  1. Check that a firewall or SELinux policy is not blocking UDP on the chosen port.
  2. Confirm the system has a usable IPv6 stack (or IPv4, matching the requested family); try forcing the other family.
  3. Run with sufficient privileges if binding a restricted port, or use an ephemeral/client port (bind to port 0).
  4. Verify no other process holds the socket if a specific local address/port is configured.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at src/client_h3.rs:94 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of hatoo/oha@4efba2d113 (2026-09-09). Data as JSON: /api/errors/1cfa239613601acb. Report an issue: GitHub.

Appendix: source

Thrown at src/client_h3.rs:94

                Ok(Ok(stream)) => stream,
                Ok(Err(err)) => return Err(err),
                Err(_) => return Err(ClientError::Timeout),
            };
        let send_request = stream.handshake_http3().await?;
        let dialup = std::time::Instant::now();
        Ok((
            ConnectionTime {
                dns_lookup: dns_lookup - start,
                dialup: dialup - start,
            },
            send_request,
        ))
    }

    fn quic_endpoint(&self, is_ipv6: bool) -> Result<quinn::Endpoint, ClientError> {
        let endpoint_config = h3_quinn::quinn::EndpointConfig::default();
        let local_socket = if is_ipv6 {
            UdpSocket::bind("[::]:0").expect("couldn't bind to address")
        } else {
            UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address")
        };
        // Enlarge UDP buffers as far as the OS allows to avoid packet loss at high rates.
        {
            let socket_ref = socket2::SockRef::from(&local_socket);
            let _ = socket_ref.set_recv_buffer_size(8 * 1024 * 1024);
            let _ = socket_ref.set_send_buffer_size(8 * 1024 * 1024);
        }
        // If we can set the right build flags, we can use `h3_quinn::quinn::Endpoint::client` instead
        let mut client_endpoint = h3_quinn::quinn::Endpoint::new(
            endpoint_config,
            None,
            local_socket,
            default_runtime().unwrap(),
        )
        .unwrap();

View on GitHub (pinned to 4efba2d113)