netbirdio/netbird · error
no relay transport available
Error message
no relay transport available
What it means
dialErr combines per-dialer failures, and returns this error only when the collected error list is empty — meaning no registered transport dialer reported any result for the requested protocol. This is distinct from dialers that ran and failed (those errors would be joined): here the race dialer had no transport available to attempt at all.
Source
Thrown at shared/relay/client/dialer/race_dialer.go:177
}
// orderedErrs returns the per-protocol errors in dialer order, so the combined
// error is stable regardless of which attempt failed first.
func (r *RaceDial) orderedErrs(byProtocol map[string]error) []error {
errs := make([]error, 0, len(byProtocol))
for _, dfn := range r.dialerFns {
if err, ok := byProtocol[dfn.Protocol()]; ok {
errs = append(errs, err)
}
}
return errs
}
// dialErr combines per-dialer failures, preserving the underlying reasons
// (e.g. "connection refused") rather than a generic message.
func dialErr(errs []error) error {
if len(errs) == 0 {
return errors.New("no relay transport available")
}
return errors.Join(errs...)
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Enable the default relay transports in the client configuration
- Rebuild without excluding transport build tags
- Upgrade the relay client so at least one transport is registered
Defensive patterns
Strategy: fallback
Validate before calling
supported := dialer.SupportedProtocols() // e.g. from your dialer registry
if len(supported) == 0 {
return fmt.Errorf("no relay transport compiled in; rebuild with default transports")
} Try / catch
conn, err := raceDialer.Dial(ctx, addr)
if err != nil {
if err.Error() == "no relay transport available" {
// configuration/build defect, not a network failure: fall back to a default transport-enabled client
}
return nil, err
} Prevention
- Assert at startup that at least one transport dialer is registered
- Do not disable transports via build tags unless another is guaranteed
- Distinguish 'no transport' from 'transport failed' in error handling
When it happens
Trigger: All transport dialers (e.g. QUIC/TCP) disabled by build tags, configuration, or platform constraints, so none attempts the relay connection.
Common situations: A binary built without a transport dependency; transports disabled via config or env; running on a platform where the only compiled transport is unavailable.
Related errors
- invalid signature
- no relay server available
- listen_port is not supported for HTTP services
- domain is required for TCP/UDP services (used for cluster de
- auth is not supported for TCP/UDP services
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/ea7cd7fc69d1c4ec.
Report an issue: GitHub.