fatedier/frp · critical
listen on quic udp address %s error: %v
Error message
listen on quic udp address %s error: %v
What it means
When QUICBindPort > 0, frps calls quic.ListenAddr on BindAddr:QUICBindPort with the server TLS config. Any failure (bind error, TLS misconfiguration) aborts service creation with the address echoed in the error.
Source
Thrown at server/service.go:275
address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.KCPBindPort))
svr.kcpListener, err = netpkg.ListenKcp(address)
if err != nil {
return nil, fmt.Errorf("listen on kcp udp address %s error: %v", address, err)
}
log.Infof("frps kcp listen on udp %s", address)
}
if cfg.QUICBindPort > 0 {
address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.QUICBindPort))
quicTLSCfg := tlsConfig.Clone()
quicTLSCfg.NextProtos = []string{"frp"}
svr.quicListener, err = quic.ListenAddr(address, quicTLSCfg, &quic.Config{
MaxIdleTimeout: time.Duration(cfg.Transport.QUIC.MaxIdleTimeout) * time.Second,
MaxIncomingStreams: int64(cfg.Transport.QUIC.MaxIncomingStreams),
KeepAlivePeriod: time.Duration(cfg.Transport.QUIC.KeepalivePeriod) * time.Second,
})
if err != nil {
return nil, fmt.Errorf("listen on quic udp address %s error: %v", address, err)
}
log.Infof("frps quic listen on %s", address)
}
if cfg.SSHTunnelGateway.BindPort > 0 {
sshGateway, err := ssh.NewGateway(cfg.SSHTunnelGateway, cfg.BindAddr, svr.sshTunnelListener)
if err != nil {
return nil, fmt.Errorf("create ssh gateway error: %v", err)
}
svr.sshTunnelGateway = sshGateway
log.Infof("frps sshTunnelGateway listen on port %d", cfg.SSHTunnelGateway.BindPort)
}
// Listen for accepting connections from client using websocket protocol.
websocketPrefix := []byte("GET " + netpkg.FrpWebsocketPath)
websocketLn := svr.muxer.Listen(0, uint32(len(websocketPrefix)), func(data []byte) bool {
return bytes.Equal(data, websocketPrefix)
})View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Free or change quicBindPort
- Validate the TLS cert/key pair configured on frps (they must parse and match)
- Confirm UDP egress/ingress is permitted if behind NAT/firewalls
- Disable quicBindPort if QUIC transport is not needed
Defensive patterns
Strategy: validation
Validate before calling
// Validate TLS material and UDP port before enabling QUIC.
if _, err := tls.LoadX509KeyPair(cfg.TLSCertFile, cfg.TLSKeyFile); err != nil {
return err
}
if c, err := net.ListenPacket("udp", addr); err != nil { return err } else { c.Close() } Prevention
- Health-check cert/key pairs in config validation, not at boot
- Confirm cloud security groups allow the QUIC UDP port in both directions
- Disable quicBindPort in environments where UDP is filtered
When it happens
Trigger: QUIC UDP port already in use; TLS certificate/key invalid so the cloned tlsConfig cannot back a QUIC listener; BindAddr not present on the host.
Common situations: Running QUIC on a port already used by another QUIC/HTTP3 service; self-signed or unreadable cert files; UDP blocked by cloud security groups.
Related errors
- listen on kcp udp address %s error: %v
- create server listener error, %v
- create vhost http listener error, %v
- create tls config error: %v
- dial quic error: %v
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/f69f683b3c859af0.
Report an issue: GitHub.