{"record":{"id":"34c9e11075eb0461","repo":"netbirdio/netbird","slug":"add-profile-failed-w","errorCode":null,"errorMessage":"add profile failed: %w","messagePattern":"add profile failed: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/profile.go","lineNumber":340,"sourceCode":"\t\t\treturn errors.New(msg + \"\\nRun `netbird profile list --show-id` to see IDs, then select by ID prefix:\\n  netbird profile select|remove <id-prefix>\")\n\t\t}\n\tcase codes.NotFound:\n\t\treturn fmt.Errorf(\"profile %q not found\", handle)\n\t}\n\treturn err\n}\n\n// addProfileOnDaemon issues the AddProfile RPC on an existing daemon client\n// and returns the new profile's ID. It is the single entry point for profile\n// creation, shared by `netbird profile add` and the `netbird up --profile\n// <name>` auto-create path.\nfunc addProfileOnDaemon(ctx context.Context, client proto.DaemonServiceClient, profileName, username string) (profilemanager.ID, error) {\n\tresp, err := client.AddProfile(ctx, &proto.AddProfileRequest{\n\t\tProfileName: profileName,\n\t\tUsername:    username,\n\t})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"add profile failed: %w\", err)\n\t}\n\n\treturn profilemanager.ID(resp.Id), nil\n}\n","sourceCodeStart":322,"sourceCodeEnd":345,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/profile.go#L322-L345","documentation":"addProfileOnDaemon (client/cmd/profile.go:332-343) is the shared entry point for profile creation used by `netbird profile add` and the `netbird up --profile <name>` auto-create path. The error wraps any AddProfile RPC failure: daemon-side validation of the profile name, storage errors, or gRPC-level failures (Unavailable while the daemon restarts). The %w wrap preserves the daemon's status message in the chain.","triggerScenarios":"Profile name rejected by daemon validation (empty, control characters, bad length); daemon's profile store unwritable; daemon restarted mid-call (Unavailable); CLI/daemon version skew where AddProfile semantics differ; duplicate handling policy on the daemon.","commonSituations":"Automating `netbird up --profile <name>` with machine-generated names containing invalid characters; full state directory permissions broken (root-owned after manual sudo use); partial upgrades between CLI and daemon.","solutions":["Retry with a simple alphanumeric profile name to rule out validation","Check the daemon's state directory permissions (usually /var/lib/netbird or the user's config dir) and daemon logs","Confirm daemon and CLI versions match (upgrade the service)","If it fails only via `up --profile`, create the profile explicitly with `netbird profile add` to see the same RPC in isolation"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"name := strings.TrimSpace(profileName)\nif name == \"\" || strings.ContainsAny(name, \"\\x00\\n\\r\\t\") {\n    return errors.New(\"profile name must be non-empty printable text\")\n}","typeGuard":"func validProfileName(s string) bool {\n    return s != \"\" && !strings.ContainsAny(s, \"\\x00\\n\\r\\t\")\n}","tryCatchPattern":"resp, err := client.AddProfile(ctx, &proto.AddProfileRequest{ProfileName: name, Username: user})\nif err != nil {\n    if st, ok := status.FromError(err); ok && st.Code() == codes.Unavailable {\n        return fmt.Errorf(\"daemon restarting during add; retry: %w\", err)\n    }\n    return fmt.Errorf(\"add profile failed: %w\", err)\n}","preventionTips":["Sanitize machine-generated profile names before passing them in","Keep daemon and CLI on the same release","Check state-directory permissions when adds fail persistently"],"tags":["profiles","grpc","validation","daemon"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}