netbirdio/netbird · error
create profile: %w
Error message
create profile: %w
What it means
Thrown by switchOrCreateProfile (client/cmd/up.go:168). Flow: switchProfile returned NotFound, then the helper called createProfile and retried switchProfile; when BOTH fail, the create error is wrapped with %w and surfaced here. The comment explains the design: a concurrent run may have created the profile between the NotFound and the create, so the create error is only reported when the retried switch also fails.
Source
Thrown at client/cmd/up.go:168
// switchOrCreateProfile switches the active profile to the one identified by
// handle, creating it first when it does not exist yet. This restores the
// pre-0.73 behaviour where `netbird up --profile <name>` auto-creates a
// missing profile instead of failing.
func switchOrCreateProfile(ctx context.Context, pm *profilemanager.ProfileManager, handle, username string) error {
resolvedID, err := switchProfile(ctx, handle, username)
if err != nil {
st, ok := gstatus.FromError(err)
if !ok || st.Code() != codes.NotFound {
return err
}
// Don't fail immediately on a create error: a concurrent run may
// have created the profile between the NotFound above and this
// call, in which case the retried switch still succeeds. Only
// surface the create error if the switch also fails.
_, createErr := createProfile(ctx, handle, username)
if resolvedID, err = switchProfile(ctx, handle, username); err != nil {
if createErr != nil {
return fmt.Errorf("create profile: %w", createErr)
}
return err
}
}
if err := pm.SwitchProfile(resolvedID); err != nil {
return err
}
return nil
}
// createProfile dials the daemon and creates a new profile with the given
// display name, returning its generated ID. Use addProfileOnDaemon directly
// when a daemon client is already available to reuse the connection.
func createProfile(ctx context.Context, profileName, username string) (profilemanager.ID, error) {
conn, err := DialClientGRPCServer(ctx, daemonAddr)
if err != nil {
//nolintView on GitHub (pinned to 93e97f4bf1)
Solutions
- Ensure the daemon is up and healthy, then simply rerun 'netbird up --profile <name>' - the retry path usually succeeds
- Check 'netbird service status'/systemctl and the daemon logs for why addProfile failed
- Align CLI and daemon versions if the RPC is missing
Defensive patterns
Strategy: retry
Validate before calling
if _, err := DialClientGRPCServer(ctx, daemonAddr); err != nil {
log.Fatal("daemon unreachable - the profile auto-create path needs it")
} Prevention
- Serialize concurrent 'netbird up --profile' runs (lock or systemd single-instance)
- Keep the daemon healthy; the create+switch retry already tolerates a single race
When it happens
Trigger: 'netbird up --profile <name>' where the daemon dial inside createProfile fails (service down - typically surfaces the nested 'failed to connect to daemon' text), or the daemon addProfile RPC rejects the request; simultaneously the retried switch also cannot resolve the handle.
Common situations: Two 'netbird up --profile' invocations racing on one machine while the daemon is flapping or being restarted; daemon running an old version without the profile RPCs.
Related errors
- switch profile: %v
- wait for extend session: %v
- switch profile: %v
- switch profile on daemon: %v
- connect to service CLI interface: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/7874f46b8d6c21e5.
Report an issue: GitHub.