netbirdio/netbird · warning
local conn: %s
Error message
local conn: %s
What it means
Appended to the close() multierror when the local UDP conn (the dial to the agent's own WireGuard listen port made in AddTurnConn) fails to close. Unlike the remote conn branch, net.ErrClosed is NOT filtered here, but the closed flag plus closeMu make double-close impossible from close() itself, so in practice this only fires on real close errors or on races where something else closed localConn.
Source
Thrown at client/iface/wgproxy/udp/proxy.go:195
return nil
}
p.closeListener.SetCloseListener(nil)
p.closed = true
p.cancel()
p.pausedCond.L.Lock()
p.paused = false
p.pausedCond.Signal()
p.pausedCond.L.Unlock()
if err := p.remoteConn.Close(); err != nil && !errors.Is(err, net.ErrClosed) {
result = multierror.Append(result, fmt.Errorf("remote conn: %s", err))
}
if err := p.localConn.Close(); err != nil {
result = multierror.Append(result, fmt.Errorf("local conn: %s", err))
}
if p.srcFakerConn != nil {
if err := p.srcFakerConn.Close(); err != nil {
result = multierror.Append(result, fmt.Errorf("src faker raw conn: %s", err))
}
}
return cerrors.FormatErrorOrNil(result)
}
// proxyToRemote proxies from Wireguard to the RemoteKey
func (p *WGUDPProxy) proxyToRemote(ctx context.Context) {
defer func() {
if err := p.close(); err != nil {
log.Warnf("error in proxy to remote loop: %s", err)
}
}()View on GitHub (pinned to 93e97f4bf1)
Solutions
- Ignore one-off occurrences during netbird down/reconnects
- If the message pairs with relay failures, restart the agent to rewire proxy and interface cleanly
- Check for custom integrations that close conns they handed to AddTurnConn
Defensive patterns
Strategy: try-catch
Try / catch
if err := p.localConn.Close(); err != nil && !errors.Is(err, net.ErrClosed) {
result = multierror.Append(result, fmt.Errorf("local conn: %w", err)) // use %w so callers can errors.Is
} Prevention
- Never close localConn externally; always route teardown through CloseConn/close so the closed flag applies
- During interface rebuilds, expect this error once and drain proxies before recreating the WG interface
- Use %w instead of %s when wrapping so callers can match sentinel errors
When it happens
Trigger: localConn already dead (local WG listener gone, e.g. interface recreate during reconnect) and the socket reporting an error on close; external code closing the conn out from under the proxy.
Common situations: Reconnect cycles where the WireGuard interface is rebuilt; shutdown ordering issues between the engine and proxy manager. Almost always transient noise accompanying a legitimate disconnect.
Related errors
- remote conn: %s
- src faker raw conn: %s
- failed to remove WireGuard interface %s: %w
- timeout when waiting for interface %s to be removed
- proxy not started
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/6f0885105fcd3684.
Report an issue: GitHub.