netbirdio/netbird · error

read service params %s: %w

Error message

read service params %s: %w

What it means

loadServiceParams could not read <stateDir>/service.json. A missing file is fine (returns nil), so this is a genuine read failure: permissions on the file or directory, or the path not being a readable regular file.

Source

Thrown at client/cmd/service_params.go:54

	ServiceEnvVars        map[string]string `json:"service_env_vars,omitempty"`
}

// serviceParamsPath returns the path to the service params file.
func serviceParamsPath() string {
	return filepath.Join(configs.StateDir, serviceParamsFile)
}

// loadServiceParams reads saved service parameters from disk.
// Returns nil with no error if the file does not exist.
func loadServiceParams() (*serviceParams, error) {
	path := serviceParamsPath()

	data, err := os.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, nil //nolint:nilnil
		}
		return nil, fmt.Errorf("read service params %s: %w", path, err)
	}

	var params serviceParams
	if err := json.Unmarshal(data, &params); err != nil {
		return nil, fmt.Errorf("parse service params %s: %w", path, err)
	}

	return &params, nil
}

// saveServiceParams writes current service parameters to disk atomically
// with restricted permissions.
func saveServiceParams(params *serviceParams) error {
	path := serviceParamsPath()
	if err := util.WriteJsonWithRestrictedPermission(context.Background(), path, params); err != nil {
		return fmt.Errorf("save service params: %w", err)
	}
	return nil

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Run the command elevated (sudo or administrator)
  2. Check ownership and mode: ls -l /var/lib/netbird/service.json
  3. Fix with chown/chmod if the file should be user-accessible
  4. As a last resort remove the file (defaults are re-derived on next install) after saving a copy
Defensive patterns

Strategy: validation

Validate before calling

path := serviceParamsPath()
if info, err := os.Stat(path); err == nil {
	if info.IsDir() {
		return fmt.Errorf("%s is a directory", path)
	}
	if info.Mode().Perm()&0o400 == 0 {
		return fmt.Errorf("no read permission on %s; run elevated", path)
	}
}

Try / catch

data, err := os.ReadFile(path)
if err != nil {
	if os.IsNotExist(err) {
		return nil, nil
	}
	return fmt.Errorf("read service params %s: %w", path, err)
}

Prevention

When it happens

Trigger: Running the CLI as an unprivileged user against a root-owned service.json under /var/lib/netbird (or C:\ProgramData\NetBird); a read-only mount; the path replaced by a directory or symlink loop.

Common situations: Inspecting or uninstalling a root-installed service from a normal user shell; hardened hosts with restrictive state directories.

Related errors


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