netbirdio/netbird · error

invalid dns labels: %w

Error message

invalid dns labels: %w

What it means

Returned by embed.New when domain.FromStringList rejects one of the Options.DNSLabels entries. Each label must parse as a valid DNS domain (per shared/management/domain parsing rules: valid label characters, length limits, no scheme or port). The wrapped error identifies the offending label.

Source

Thrown at client/embed/embed.go:192

		if err := os.Setenv(netstack.EnvUseNetstackMode, "true"); err != nil {
			return nil, fmt.Errorf("setenv: %w", err)
		}
		if err := os.Setenv(netstack.EnvSkipProxy, "true"); err != nil {
			return nil, fmt.Errorf("setenv: %w", err)
		}
	}

	if opts.StatePath != "" {
		// TODO: Disable state if path not provided
		if err := os.Setenv("NB_DNS_STATE_FILE", opts.StatePath); err != nil {
			return nil, fmt.Errorf("setenv: %w", err)
		}
	}

	var err error
	var parsedLabels domain.List
	if parsedLabels, err = domain.FromStringList(opts.DNSLabels); err != nil {
		return nil, fmt.Errorf("invalid dns labels: %w", err)
	}

	t := true
	var config *profilemanager.Config
	input := profilemanager.ConfigInput{
		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 != "" {

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Pass only bare DNS-valid labels (alphanumeric plus hyphen, each label 1-63 chars) in DNSLabels.
  2. Validate with domain.FromStringList before embed.New when labels come from user input.
  3. Check the wrapped error message for the exact label that failed and fix or drop that entry.

Example fix

// before
client, err := embed.New(embed.Options{DNSLabels: []string{"my service", "svc.internal:8080"}})

// after
client, err := embed.New(embed.Options{DNSLabels: []string{"my-service", "svc-internal"}})
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/netbirdio/netbird/shared/management/domain"

if _, err := domain.FromStringList(opts.DNSLabels); err != nil {
    return fmt.Errorf("reject labels before embed.New: %w", err)
}

Prevention

When it happens

Trigger: Calling embed.New with DNSLabels containing entries like "my label" (space), "label;other", "http://svc", "svc:8080", an empty string, or a label longer than 63 characters.

Common situations: Reusing service names, URLs, or host:port strings as DNS labels; splitting a comma-separated label config on the wrong delimiter leaving empty strings; copy-pasting FQDNs with trailing dots or underscores where the parser does not accept them.

Related errors


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