{"record":{"id":"7874f46b8d6c21e5","repo":"netbirdio/netbird","slug":"create-profile-w","errorCode":null,"errorMessage":"create profile: %w","messagePattern":"create profile: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/up.go","lineNumber":168,"sourceCode":"// switchOrCreateProfile switches the active profile to the one identified by\n// handle, creating it first when it does not exist yet. This restores the\n// pre-0.73 behaviour where `netbird up --profile <name>` auto-creates a\n// missing profile instead of failing.\nfunc switchOrCreateProfile(ctx context.Context, pm *profilemanager.ProfileManager, handle, username string) error {\n\tresolvedID, err := switchProfile(ctx, handle, username)\n\tif err != nil {\n\t\tst, ok := gstatus.FromError(err)\n\t\tif !ok || st.Code() != codes.NotFound {\n\t\t\treturn err\n\t\t}\n\t\t// Don't fail immediately on a create error: a concurrent run may\n\t\t// have created the profile between the NotFound above and this\n\t\t// call, in which case the retried switch still succeeds. Only\n\t\t// surface the create error if the switch also fails.\n\t\t_, createErr := createProfile(ctx, handle, username)\n\t\tif resolvedID, err = switchProfile(ctx, handle, username); err != nil {\n\t\t\tif createErr != nil {\n\t\t\t\treturn fmt.Errorf(\"create profile: %w\", createErr)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err := pm.SwitchProfile(resolvedID); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// createProfile dials the daemon and creates a new profile with the given\n// display name, returning its generated ID. Use addProfileOnDaemon directly\n// when a daemon client is already available to reuse the connection.\nfunc createProfile(ctx context.Context, profileName, username string) (profilemanager.ID, error) {\n\tconn, err := DialClientGRPCServer(ctx, daemonAddr)\n\tif err != nil {\n\t\t//nolint","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/up.go#L150-L186","documentation":"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.","triggerScenarios":"'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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if _, err := DialClientGRPCServer(ctx, daemonAddr); err != nil {\n    log.Fatal(\"daemon unreachable - the profile auto-create path needs it\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Serialize concurrent 'netbird up --profile' runs (lock or systemd single-instance)","Keep the daemon healthy; the create+switch retry already tolerates a single race"],"tags":["cli","daemon","profiles","concurrency","netbird"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}