netbirdio/netbird · error

read config file %s: %v

Error message

read config file %s: %v

What it means

profilemanager.ReadConfig failed on the resolved config file path: the per-profile JSON either does not exist, cannot be opened (permissions), or does not parse. The config file is created when the profile is created; this error means it was deleted, corrupted (partial write), or its ownership/permissions changed after creation.

Source

Thrown at client/cmd/login.go:333

func doForegroundLogin(ctx context.Context, cmd *cobra.Command, setupKey string, activeProf *profilemanager.Profile) error {

	err := handleRebrand(cmd)
	if err != nil {
		return err
	}

	// update host's static platform and system information
	system.UpdateStaticInfoAsync()

	configFilePath, err := activeProf.FilePath()
	if err != nil {
		return fmt.Errorf("get active profile file path: %v", err)

	}

	config, err := profilemanager.ReadConfig(configFilePath)
	if err != nil {
		return fmt.Errorf("read config file %s: %v", configFilePath, err)
	}

	// Mirror runInForegroundMode: recover residual state (DNS, firewall,
	// ssh config, legacy routing) from a previous unclean shutdown and
	// enable advanced routing before dialing management.
	if err := server.RestoreResidualState(ctx, profilemanager.NewServiceManager(configFilePath).GetStatePath()); err != nil {
		log.Warnf("failed to restore residual state: %v", err)
	}
	nbnet.Init()

	err = foregroundLogin(ctx, cmd, config, setupKey, activeProf.ID)
	if err != nil {
		return fmt.Errorf("foreground login failed: %v", err)
	}
	cmd.Println("Logging successfully")
	return nil
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Check the path printed in the error: confirm existence and ownership (ls -l <path>)
  2. Fix permissions/ownership on the file and config dir (chown to the invoking user)
  3. If the file is missing or corrupt, recreate the profile ('netbird profile create' with the same management URL) so a fresh config is written, then login again
  4. Keep the setup key or SSO credentials at hand since re-registration may be required

Example fix

# before
$ netbird login
Error: read config file /home/user/.netbird/config.json: open ...: permission denied

# after
$ sudo chown "$USER:" /home/user/.netbird/config.json
$ netbird login
Defensive patterns

Strategy: validation

Validate before calling

// Existence + readability check before ReadConfig
info, err := os.Stat(configFilePath)
if err != nil {
    return fmt.Errorf("config file missing: %w", err)
}
if info.Mode().Perm()&0o400 == 0 {
    return fmt.Errorf("config file %s not readable by this user", configFilePath)
}

Try / catch

config, err := profilemanager.ReadConfig(configFilePath)
if err != nil {
    if errors.Is(err, os.ErrNotExist) {
        // recreate the profile rather than failing the whole login
        return recreateProfileAndLogin(ctx, configFilePath)
    }
    if isJSONErr(err) {
        return fmt.Errorf("config corrupted, recreate profile: %w", err)
    }
    return fmt.Errorf("read config file %s: %w", configFilePath, err)
}

Prevention

When it happens

Trigger: Config file deleted or moved after profile creation; truncated JSON from an interrupted write (crash during save); ownership changed by running the daemon/CLI once under a different account (e.g., sudo); disk corruption.

Common situations: Mixed sudo/non-sudo usage leaving root-owned config files; Backup restores that skipped dotfiles; Cleanup scripts aggressively pruning ~/.netbird

Related errors


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