netbirdio/netbird · warning
tun module not available
Error message
tun module not available
What it means
handleHeaderAuthError (middleware.go:498) fires when a header scheme's Authenticate returned ErrHeaderAuthFailed, meaning the presented header credentials were syntactically processable but authentication failed (e.g. wrong username/password or bad credential header per the scheme). This is a clean 401, distinct from infrastructure errors at the same helper which produce 502.
Source
Thrown at client/iface/iface_new_linux.go:41
}
if device.WireGuardModuleIsLoaded() {
return &WGIface{
tun: device.NewKernelDevice(opts.IFaceName, opts.Address, opts.WGPort, opts.WGPrivKey, opts.MTU, opts.TransportNet),
wgProxyFactory: wgproxy.NewKernelFactory(opts.WGPort, opts.MTU),
}, nil
}
if device.ModuleTunIsLoaded() {
iceBind := bind.NewICEBind(opts.TransportNet, opts.Address, opts.MTU)
return &WGIface{
tun: device.NewTunDevice(opts.IFaceName, opts.Address, opts.WGPort, opts.WGPrivKey, opts.MTU, iceBind),
userspaceBind: true,
wgProxyFactory: wgproxy.NewUSPFactory(iceBind, opts.MTU),
}, nil
}
return nil, errors.New("tun module not available")
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Verify the exact header name and credential format the domain's header scheme expects (values are compared as the scheme defines, not as a generic bearer token).
- Rotate/refresh the credential on the client and retry.
- Confirm the operator account backing the credential is still active in management.
- Check that only one scheme is registered for the domain if headers could collide between schemes.
Defensive patterns
Strategy: validation
Validate before calling
// Before calling: confirm the credential is present and matches the scheme's
// expected header format exactly.
if v := strings.TrimSpace(os.Getenv("NB_HEADER_CRED")); v == "" {
return errors.New("header credential missing: set NB_HEADER_CRED")
} Try / catch
resp, err := client.Do(req)
if err == nil && resp.StatusCode == http.StatusUnauthorized {
// Header credentials rejected (not infrastructure): rotate the secret,
// verify header name/format against the domain's scheme, retry once.
} Prevention
- Pin the exact header name and value format the domain's header scheme defines.
- Rotate credentials before expiry and update all clients atomically.
- Distinguish 401 (credentials wrong) from 502 (backend down) before touching secrets.
- Avoid registering colliding header schemes on the same domain.
When it happens
Trigger: A request whose header scheme trigger is present (the header the scheme watches) with credentials that fail validation — wrong value, wrong format for the scheme, credentials for a different operator/user, or a basic-auth pair that does not match.
Common situations: API key or password rotated and the client still sends the old one; typo in the header name causing an unintended scheme to consume the request; CI secret expired; user account behind the credentials disabled in management.
Related errors
- host argument required
- client already started
- engine not started
- engine is not initialized
- sync response is not available
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/723a8c7af4919268.
Report an issue: GitHub.