netbirdio/netbird · error

failed to resolve active profile %q: %w

Error message

failed to resolve active profile %q: %w

What it means

active_profile.json was read successfully, but ServiceManager.ResolveProfile could not find or load the profile config the stored ID points to. The state is stale: the profile file was deleted, renamed out-of-band, or never existed under profiles/ (or netbird.cfg for the default profile). The offending ID is included in the message.

Source

Thrown at client/android/profile_manager.go:125

	}

	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.
func (pm *ProfileManager) profileEmail(id string) string {
	configPath, err := pm.getProfileConfigPath(id)
	if err != nil {
		return ""
	}
	return readProfileEmail(configPath)
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Call ListProfiles to see which profiles actually exist on disk
  2. Re-point the state with SwitchProfile to an existing profile id (or "default")
  3. Or delete active_profile.json so the next activation recreates it
  4. If the config files were lost, log in again to recreate the profile

Example fix

// before
active, err := pm.GetActiveProfile() // fails: dangling id in active_profile.json

// after: reset the active state to a profile that exists
if _, err := pm.GetActiveProfile(); err != nil {
	_ = pm.SwitchProfile("default") // or an id confirmed via ListProfiles
}
Defensive patterns

Strategy: fallback

Validate before calling

// Before trusting the active id, confirm its config exists
list, err := pm.ListProfiles()
if err == nil && !containsId(list, activeId) {
	// dangling state: re-switch instead of calling GetActiveProfile
}

Try / catch

if _, err := pm.GetActiveProfile(); err != nil && strings.Contains(err.Error(), "failed to resolve active profile") {
	_ = pm.SwitchProfile("default") // reset the stale pointer, then retry
	_, _ = pm.GetActiveProfile()
}

Prevention

When it happens

Trigger: active_profile.json references an id whose file was removed outside RemoveProfile (file manager, crashed removal leaving the state file behind), a config-dir migration lost the profile files, or the default profile is active but netbird.cfg is absent.

Common situations: Partial app-data restore, manual file deletion, interrupted RemoveProfile, config directory moved between app versions.

Related errors


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