netbirdio/netbird · warning

failed to get active profile: %w

Error message

failed to get active profile: %w

What it means

GetActiveProfile reads configDir/active_profile.json through ServiceManager.GetActiveProfileState. This error means that file could not be turned into state: it is missing (no profile was ever activated — the normal fresh-install condition), unreadable, or malformed JSON. The underlying read/parse error is wrapped.

Source

Thrown at client/android/profile_manager.go:118

	for _, p := range internalProfiles {
		profiles = append(profiles, &Profile{
			ID:       p.ID.String(),
			Name:     p.Name,
			Email:    pm.profileEmail(p.ID.String()),
			IsActive: p.IsActive,
		})
	}

	return &ProfileArray{items: profiles}, nil
}

// GetActiveProfile returns the currently active profile name
func (pm *ProfileManager) GetActiveProfile() (*Profile, error) {
	// Use ServiceManager to stay consistent with ListProfiles
	// ServiceManager uses active_profile.json
	activeState, err := pm.serviceMgr.GetActiveProfileState()
	if err != nil {
		return nil, fmt.Errorf("failed to get active profile: %w", err)
	}

	// ActiveProfileState only stores the ID (and username), not the display
	// name. Resolve the ID to the full profile so callers get the real Name.
	prof, err := pm.serviceMgr.ResolveProfile(activeState.ID.String(), androidUsername)
	if err != nil {
		return nil, fmt.Errorf("failed to resolve active profile %q: %w", activeState.ID, err)
	}
	return &Profile{
		ID:       prof.ID.String(),
		Name:     prof.Name,
		Email:    pm.profileEmail(prof.ID.String()),
		IsActive: true,
	}, nil
}

// profileEmail returns the account email recorded for a profile. Display-only, so
// an unresolvable path degrades to "" rather than an error.

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. On fresh installs, establish a profile first: AddProfile/SwitchProfile or a first login writes active_profile.json
  2. If the file is corrupt, delete active_profile.json and switch to an existing profile to regenerate it
  3. Treat the error as 'no active profile yet' in the UI rather than a hard failure

Example fix

// before: assume an active profile always exists
p, err := pm.GetActiveProfile() // fails on fresh install

// after: handle the no-active-profile case
p, err := pm.GetActiveProfile()
if err != nil {
	_ = pm.SwitchProfile("default") // or prompt the user to log in
	p, err = pm.GetActiveProfile()
}
Defensive patterns

Strategy: fallback

Validate before calling

// Check the state file before assuming an active profile exists
if _, err := os.Stat(filepath.Join(configDir, "active_profile.json")); os.IsNotExist(err) {
	// fresh install: use the default profile instead of calling GetActiveProfile
}

Try / catch

p, err := pm.GetActiveProfile()
if err != nil {
	// no usable active state: fall back to default and/or prompt first login
	_ = pm.SwitchProfile("default")
	p, err = pm.GetActiveProfile()
}

Prevention

When it happens

Trigger: GetActiveProfile (directly or via GetActiveConfigPath/GetActiveStateFilePath) is called before any SwitchProfile, AddProfile, or first-run login created active_profile.json; or the file is corrupt after an interrupted write or partial data clear.

Common situations: First app launch, app data cleared, backup restored only some files, file truncated by a disk-full write.

Related errors


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