slackhq/nebula · error
only tcp is supported
Error message
only tcp is supported
What it means
Service.Listen exposes a net.Listener over the nebula tunnel, but the underlying implementation only supports TCP. Passing any network other than "tcp" or "tcp4" returns this error immediately. UDP/unix/other network types are not implemented.
Source
Thrown at service/service.go:212
Port: uint16(addr.Port),
}
num := getProtocolNumber(addr.AddrPort().Addr())
return gonet.DialContextTCP(ctx, s.ipstack, fullAddr, num)
default:
return nil, fmt.Errorf("unknown network type: %s", network)
}
}
// Dial dials the provided address
func (s *Service) Dial(network, address string) (net.Conn, error) {
return s.DialContext(context.Background(), network, address)
}
// Listen listens on the provided address. Currently only TCP with wildcard
// addresses are supported.
func (s *Service) Listen(network, address string) (net.Listener, error) {
if network != "tcp" && network != "tcp4" {
return nil, errors.New("only tcp is supported")
}
addr, err := net.ResolveTCPAddr(network, address)
if err != nil {
return nil, err
}
if addr.IP != nil && !bytes.Equal(addr.IP, []byte{0, 0, 0, 0}) {
return nil, fmt.Errorf("only wildcard address supported, got %q %v", address, addr.IP)
}
if addr.Port == 0 {
return nil, errors.New("specific port required, got 0")
}
if addr.Port < 0 || addr.Port >= math.MaxUint16 {
return nil, fmt.Errorf("invalid port %d", addr.Port)
}
port := uint16(addr.Port)
l := &tcpListener{
port: port,View on GitHub (pinned to dd8f660c0a)
Solutions
- Change the network argument to "tcp" or "tcp4".
- Listen for UDP traffic via the tunnel with a different API — Service.Listen does not support datagram sockets.
- Normalize tcp6 requests to tcp4 since only wildcard IPv4 addresses are supported.
Example fix
// before
ln, err := s.Listen("udp", "127.0.0.1:8080")
// after
ln, err := s.Listen("tcp", "0.0.0.0:8080") Defensive patterns
Strategy: validation
Validate before calling
if network != "tcp" && network != "tcp4" {
return fmt.Errorf("Service.Listen supports only tcp/tcp4, got %q", network)
} Try / catch
ln, err := s.Listen(network, address)
if err != nil {
if err.Error() == "only tcp is supported" {
return fmt.Errorf("use network \"tcp\" or \"tcp4\" with Service.Listen")
}
return err
} Prevention
- Hardcode "tcp" (or map tcp6 → tcp4) when calling Service.Listen
- Handle UDP needs with a separate mechanism — Listen is stream-only
- Centralize listener creation so the network literal is validated once
When it happens
Trigger: Calling s.Listen(network, address) with network values like "udp", "udp4", "unix", "tcp6" (note tcp6 is rejected; only tcp and tcp4 pass).
Common situations: Porting code that used net.Listen with "udp"; assuming tcp6 works since the address may be IPv4-mapped; generic proxy code parameterizing the network string.
Related errors
- specific port required, got 0
- unable to find host
- unable to find host with relay
- no outside connection
- no inside interface (tun)
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/4816f0303e65aa66.
Report an issue: GitHub.