netbirdio/netbird · error
invalid MTU: %w
Error message
invalid MTU: %w
What it means
Returned by embed.New when Options.MTU is non-nil and fails iface.ValidateMTU, which enforces the range 576..8192 bytes (MinMTU/MaxMTU in client/iface/iface.go). The MTU is validated eagerly at construction so an out-of-range value never reaches the tunnel interface. The wrapped error states whether the value is below the minimum or above the maximum.
Source
Thrown at client/embed/embed.go:157
if credentialsProvided == 0 {
return fmt.Errorf("one of SetupKey, JWTToken, or PrivateKey must be provided")
}
if credentialsProvided > 1 {
return fmt.Errorf("only one of SetupKey, JWTToken, or PrivateKey can be specified")
}
return nil
}
// New creates a new netbird embedded client.
func New(opts Options) (*Client, error) {
if err := opts.validateCredentials(); err != nil {
return nil, err
}
if opts.MTU != nil {
if err := iface.ValidateMTU(*opts.MTU); err != nil {
return nil, fmt.Errorf("invalid MTU: %w", err)
}
}
if opts.LogOutput != nil {
logrus.SetOutput(opts.LogOutput)
}
if opts.LogLevel != "" {
level, err := logrus.ParseLevel(opts.LogLevel)
if err != nil {
return nil, fmt.Errorf("parse log level: %w", err)
}
logrus.SetLevel(level)
}
if !opts.NoUserspace {
if err := os.Setenv(netstack.EnvUseNetstackMode, "true"); err != nil {
return nil, fmt.Errorf("setenv: %w", err)View on GitHub (pinned to 93e97f4bf1)
Solutions
- Set Options.MTU to a value in 576..8192; 1280 is the default (iface.DefaultMTU) and 1400 is typical when carrying QUIC.
- Leave Options.MTU nil to keep the existing config MTU or fall back to the default instead of passing 0.
- Call iface.ValidateMTU(mtu) yourself before embed.New to produce the error at your own validation boundary with your own message.
Example fix
// before
mtu := uint16(0) // means "unset" in the caller's config
client, err := embed.New(embed.Options{MTU: &mtu})
// after
var mtu *uint16
if cfgMTU > 0 {
m := uint16(cfgMTU)
mtu = &m
}
client, err := embed.New(embed.Options{MTU: mtu}) Defensive patterns
Strategy: validation
Validate before calling
import "github.com/netbirdio/netbird/client/iface"
if opts.MTU != nil {
if err := iface.ValidateMTU(*opts.MTU); err != nil {
return fmt.Errorf("reject options before embed.New: %w", err)
}
} Prevention
- Centralize MTU construction in one helper that only produces values in 576..8192 or nil.
- Treat 0 as 'unset' and convert it to a nil *uint16 before passing Options.
When it happens
Trigger: Calling embed.New with MTU set to a pointer holding a value < 576 (e.g. 512 or 0 copied from a default uint16) or > 8192 (e.g. 9000 'jumbo frame' values or a value read from a config that used a different unit).
Common situations: Copying an MTU tuned for a physical NIC (1500/9000) into the overlay config; treating 0 as 'unset' while the API uses a nil pointer for 'unset'; reading MTU from a JSON/YAML config as int and truncating/overflowing into uint16.
Related errors
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/40d945d60b3a71bd.
Report an issue: GitHub.