netbirdio/netbird · error

profile %q not found

Error message

profile %q not found

What it means

wrapAmbiguityError (client/cmd/profile.go:315-327) translates a codes.NotFound gRPC error from SwitchProfile/RemoveProfile/RenameProfile into 'profile %q not found'. The daemon resolves the handle (profile name or short-ID prefix) among the current user's profiles; a handle matching nothing yields NotFound. A sibling case, InvalidArgument containing 'ambiguous', produces the --show-id guidance instead.

Source

Thrown at client/cmd/profile.go:325

// wrapAmbiguityError turns the daemon's gRPC InvalidArgument errors
// (which carry the resolver's message verbatim) into CLI-friendly text
// that points the user at --show-id.
func wrapAmbiguityError(err error, handle string) error {
	if err == nil {
		return nil
	}
	st, ok := gstatus.FromError(err)
	if !ok {
		return err
	}
	switch st.Code() {
	case codes.InvalidArgument:
		msg := st.Message()
		if strings.Contains(msg, "ambiguous") {
			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

  1. List what exists for this user: `netbird profile list --show-id`, then use the printed ID or exact name
  2. Verify you are running as the same OS user that created the profile (the lookup is username-scoped)
  3. For ambiguous-name errors, switch to the unique ID prefix shown by --show-id
  4. Update scripts to reference IDs rather than display names

Example fix

# before
netbird profile select myprofile   # -> profile "myprofile" not found
# after
netbird profile list --show-id
netbird profile select ab12        # unique short-ID prefix from the list
Defensive patterns

Strategy: validation

Validate before calling

// Validate the handle against the daemon's own view before mutating
// CLI equivalent:
//   netbird profile list --show-id
// then pass the exact name or a unique short-ID prefix printed there.

Type guard

func isKnownProfile(handle string, listed []ProfileView) bool {
    for _, p := range listed {
        if p.Name == handle || strings.HasPrefix(p.ShortID, handle) {
            return true
        }
    }
    return false
}

Try / catch

err := daemonClient.SwitchProfile(ctx, req) // or RemoveProfile/RenameProfile
if err != nil {
    if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound {
        return fmt.Errorf("profile %q not found; run `netbird profile list --show-id`", handle)
    }
    return err
}

Prevention

When it happens

Trigger: Passing a name or ID prefix that matches no profile for this OS user; profile was deleted in another terminal; typo in the handle; wrong user context (username scopes the lookup); handle is a prefix too short to match after profiles changed.

Common situations: Deleting by name when the profile was created under a different name; using a truncated ID that no longer matches; multiple users on one machine each with their own profiles; stale docs/scripts referencing old profile names.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/1895acbfade3f327. Report an issue: GitHub.