fatedier/frp · error
no external address found
Error message
no external address found
What it means
Returned by discoverFromStunServer in pkg/nathole/discovery.go when a STUN binding response arrives but contains no MAPPED-ADDRESS attribute, so externalAddr stays empty. A STUN reply without a mapped address carries no information about the observer's public endpoint, so discovery from that server is useless and fails.
Source
Thrown at pkg/nathole/discovery.go:126
}
resp := &stunResponse{}
if response.MappedAddr != nil {
resp.externalAddr = response.MappedAddr.String()
}
if response.OtherAddr != nil {
resp.otherAddr = response.OtherAddr.String()
}
return resp, nil
}
func (c *discoverConn) discoverFromStunServer(addr string) ([]string, error) {
resp, err := c.doSTUNRequest(addr)
if err != nil {
return nil, err
}
if resp.externalAddr == "" {
return nil, fmt.Errorf("no external address found")
}
externalAddrs := make([]string, 0, 2)
externalAddrs = append(externalAddrs, resp.externalAddr)
if resp.otherAddr == "" {
return externalAddrs, nil
}
// find external address from changed address
resp, err = c.doSTUNRequest(resp.otherAddr)
if err != nil {
return nil, err
}
if resp.externalAddr != "" {
externalAddrs = append(externalAddrs, resp.externalAddr)
}
return externalAddrs, nilView on GitHub (pinned to 6c8a8d0a97)
Solutions
- Replace the STUN server with a known-compliant one (standard RFC 5389/8489 servers)
- Verify the port — most STUN servers listen on 3478 UDP
- Confirm nothing on the path intercepts and answers the UDP traffic
- Use multiple STUN servers so one bad entry does not kill discovery
Example fix
# before natHoleSTUNServer = ["203.0.113.10:3478"] # answers, but never maps # after natHoleSTUNServer = ["stun.easyvoip.com:3478", "stun.l.google.com:19302"]
Defensive patterns
Strategy: fallback
Try / catch
if err != nil {
if strings.Contains(err.Error(), "no external address found") {
// this server is not a healthy STUN endpoint: skip it and use the next configured server
}
} Prevention
- Use well-known RFC-compliant STUN servers on port 3478
- Validate STUN entries once at startup and drop non-responsive ones
- Do not point natHoleSTUNServer at arbitrary UDP services
When it happens
Trigger: discoverFromStunServer(addr) where the server responded but response.MappedAddr is nil. Causes: a misbehaving or non-compliant STUN server, a proxy/redirector answering UDP on that port with non-STUN data that happened to parse, or protocol-version mismatch in the STUN exchange.
Common situations: Pointing natHoleSTUNServer at a host that is not actually a STUN server; a STUN server that answers errors only; middleboxes (transparent proxies) replying to arbitrary UDP; a server that only speaks an incompatible STUN flavor.
Related errors
- wait response from stun server timeout
- discover error: %v
- not enough addresses
- proxy [%s] is repeated
- xtcp server for [%s] doesn't exist
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/49bca82903f56dd0.
Report an issue: GitHub.