netbirdio/netbird · error

create config: %w

Error message

create config: %w

What it means

Returned by embed.New when the profile manager cannot produce a configuration: profilemanager.UpdateOrCreateConfig when Options.ConfigPath is set (load/update the JSON config file) or profilemanager.CreateInMemoryConfig otherwise. The wrapped error comes from parsing the existing config file, reading/writing the path, or normalizing fields such as the management URL or pre-shared key.

Source

Thrown at client/embed/embed.go:216

		ConfigPath:          opts.ConfigPath,
		ManagementURL:       opts.ManagementURL,
		PreSharedKey:        &opts.PreSharedKey,
		DisableServerRoutes: &t,
		DisableClientRoutes: &opts.DisableClientRoutes,
		DisableIPv6:         &opts.DisableIPv6,
		BlockInbound:        &opts.BlockInbound,
		BlockLANAccess:      &opts.BlockLANAccess,
		WireguardPort:       opts.WireguardPort,
		MTU:                 opts.MTU,
		DNSLabels:           parsedLabels,
	}
	if opts.ConfigPath != "" {
		config, err = profilemanager.UpdateOrCreateConfig(input)
	} else {
		config, err = profilemanager.CreateInMemoryConfig(input)
	}
	if err != nil {
		return nil, fmt.Errorf("create config: %w", err)
	}

	if opts.PrivateKey != "" {
		config.PrivateKey = opts.PrivateKey
	}

	if opts.Performance.PreallocatedBuffersPerPool != nil {
		wgdevice.SetPreallocatedBuffersPerPool(*opts.Performance.PreallocatedBuffersPerPool)
	}
	if opts.Performance.MaxBatchSize != nil {
		wgdevice.SetMaxBatchSizeOverride(*opts.Performance.MaxBatchSize)
	}

	return &Client{
		deviceName: opts.DeviceName,
		setupKey:   opts.SetupKey,
		jwtToken:   opts.JWTToken,
		config:     config,

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Check the wrapped error: file/permission problems point at ConfigPath, parse problems at the file content.
  2. Ensure the ConfigPath directory exists and the process has read/write access, or delete the corrupt file to regenerate it.
  3. Verify ManagementURL has a valid scheme+host and the PreSharedKey is a valid key string.
  4. If you do not need persistence, leave ConfigPath empty to use the in-memory config path.

Example fix

// before
client, err := embed.New(embed.Options{ConfigPath: "/etc/netbird/embed.json", ...})

// after
if err := os.MkdirAll(filepath.Dir(cfgPath), 0o700); err != nil { return err }
client, err := embed.New(embed.Options{ConfigPath: cfgPath, ...})
Defensive patterns

Strategy: validation

Validate before calling

if opts.ConfigPath != "" {
    if err := os.MkdirAll(filepath.Dir(opts.ConfigPath), 0o700); err != nil {
        return err
    }
    if _, err := os.Stat(opts.ConfigPath); err == nil {
        if data, rerr := os.ReadFile(opts.ConfigPath); rerr != nil || !json.Valid(data) {
            return fmt.Errorf("existing config unreadable/corrupt: remove %s", opts.ConfigPath)
        }
    }
}

Try / catch

client, err := embed.New(opts)
if err != nil {
    if strings.Contains(err.Error(), "create config") {
        // decide: regenerate config from scratch (delete file) or surface to user
    }
}

Prevention

When it happens

Trigger: embed.New with ConfigPath pointing to a missing directory, a corrupt or non-JSON existing config file, a file the process cannot read/write (permissions), or with an invalid ManagementURL / PreSharedKey that fails config normalization.

Common situations: Running the embedding binary without write access to the config location; a partially written config from a crashed previous run; a management URL copied with a typo or missing scheme; a pre-shared key in the wrong base64 format; switching ConfigPath between versions whose config schema changed.

Related errors


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