netbirdio/netbird · error
error configuring interface: %s
Error message
error configuring interface: %s
What it means
Thrown by TunNetstackDevice.create() in netstack mode, where wireguard-go runs over a gVisor userspace stack with no OS tun device. After the device is constructed, WGUSPConfigurerNoUAPI.ConfigureInterface parses the WireGuard private key with wgtypes.ParseKey and applies private_key/listen_port/fwmark via device.IpcSet. This error wraps any failure of that step; the netstack tun is closed and create() returns nil.
Source
Thrown at client/iface/device/device_netstack.go:93
if err != nil {
return nil, fmt.Errorf("error creating tun device: %s", err)
}
t.filteredDevice = newDeviceFilter(tunIface)
t.net = net
t.device = device.NewDevice(
t.filteredDevice,
t.bind,
device.NewLogger(wgLogLevel(), "[netbird] "),
)
t.configurer = configurer.NewUSPConfigurerNoUAPI(t.device, t.name, t.bind.ActivityRecorder())
err = t.configurer.ConfigureInterface(t.key, t.port)
if err != nil {
if cErr := tunIface.Close(); cErr != nil {
log.Debugf("failed to close tun device: %v", cErr)
}
return nil, fmt.Errorf("error configuring interface: %s", err)
}
log.Debugf("device has been created: %s", t.name)
return t.configurer, nil
}
func (t *TunNetstackDevice) Up() (*udpmux.UniversalUDPMuxDefault, error) {
if t.device == nil {
return nil, fmt.Errorf("device is not ready yet")
}
err := t.device.Up()
if err != nil {
return nil, err
}
udpMux, err := t.bind.GetICEMux()
if err != nil && !errors.Is(err, bind.ErrUDPMUXNotSupported) {View on GitHub (pinned to 93e97f4bf1)
Solutions
- Validate the private key with wgtypes.ParseKey before constructing the device and fail fast with a clear message
- Ensure the wg port passed to NewNetstackDevice is within 1-65535 and not already bound by another instance
- Enable debug logging to capture the exact ParseKey/IpcSet error text under 'error configuring interface:'
- If agent state is corrupted, re-register to generate a fresh key
Example fix
// before
dev := device.NewNetstackDevice(name, addr, port, key, mtu, bind, listenAddr)
cfg, err := dev.Create()
// after
if _, kerr := wgtypes.ParseKey(key); kerr != nil {
return fmt.Errorf("invalid private key: %w", kerr)
}
dev := device.NewNetstackDevice(name, addr, port, key, mtu, bind, listenAddr)
cfg, err := dev.Create() Defensive patterns
Strategy: validation
Validate before calling
if _, err := wgtypes.ParseKey(privateKey); err != nil {
return fmt.Errorf("invalid WireGuard private key: %w", err)
}
if port < 1 || port > 65535 {
return fmt.Errorf("invalid listen port %d", port)
} Try / catch
cfg, err := dev.Create()
if err != nil {
if strings.HasPrefix(err.Error(), "error configuring interface") {
// key or IpcSet problem: inspect wrapped cause in logs, do not blind-retry
}
return err
} Prevention
- Validate WireGuard keys at the boundary where they are loaded from state before any device work
- Bound the listen port to 1-65535 at construction time
- Never ignore a Create() error; it leaves the device half-built
When it happens
Trigger: wgtypes.ParseKey rejecting t.key (not a 32-byte base64 key), or device.IpcSet rejecting the listen_port/fwmark value, or running against a device closed concurrently.
Common situations: Corrupted or regenerated WireGuard key in agent state, an out-of-range port passed to NewNetstackDevice, calling create() twice or Close() racing Create() in embedded (client/embed) usage.
Related errors
- error configuring interface: %s
- output DNAT not supported without native firewall
- failed to parse endpoint address: %w
- listen_port is not supported for HTTP services
- domain is required for TCP/UDP services (used for cluster de
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/556a99dd640c1e8e.
Report an issue: GitHub.