netbirdio/netbird · error
add profile failed: %w
Error message
add profile failed: %w
What it means
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.
Source
Thrown at client/cmd/profile.go:340
return errors.New(msg + "\nRun `netbird profile list --show-id` to see IDs, then select by ID prefix:\n netbird profile select|remove <id-prefix>")
}
case codes.NotFound:
return fmt.Errorf("profile %q not found", handle)
}
return err
}
// addProfileOnDaemon issues the AddProfile RPC on an existing daemon client
// and returns the new profile's ID. It is the single entry point for profile
// creation, shared by `netbird profile add` and the `netbird up --profile
// <name>` auto-create path.
func addProfileOnDaemon(ctx context.Context, client proto.DaemonServiceClient, profileName, username string) (profilemanager.ID, error) {
resp, err := client.AddProfile(ctx, &proto.AddProfileRequest{
ProfileName: profileName,
Username: username,
})
if err != nil {
return "", fmt.Errorf("add profile failed: %w", err)
}
return profilemanager.ID(resp.Id), nil
}
View on GitHub (pinned to 93e97f4bf1)
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
Defensive patterns
Strategy: validation
Validate before calling
name := strings.TrimSpace(profileName)
if name == "" || strings.ContainsAny(name, "\x00\n\r\t") {
return errors.New("profile name must be non-empty printable text")
} Type guard
func validProfileName(s string) bool {
return s != "" && !strings.ContainsAny(s, "\x00\n\r\t")
} Try / catch
resp, err := client.AddProfile(ctx, &proto.AddProfileRequest{ProfileName: name, Username: user})
if err != nil {
if st, ok := status.FromError(err); ok && st.Code() == codes.Unavailable {
return fmt.Errorf("daemon restarting during add; retry: %w", err)
}
return fmt.Errorf("add profile failed: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/34c9e11075eb0461.
Report an issue: GitHub.