netbirdio/netbird · error

parse log level: %w

Error message

parse log level: %w

What it means

Returned by embed.New when Options.LogLevel is non-empty and logrus.ParseLevel rejects it. Valid levels are panic, fatal, error, warn, warning, info, debug and trace (case-insensitive). The embedded client reuses the process-global logrus logger, so the level must be a valid logrus level string.

Source

Thrown at client/embed/embed.go:168

func New(opts Options) (*Client, error) {
	if err := opts.validateCredentials(); err != nil {
		return nil, err
	}

	if opts.MTU != nil {
		if err := iface.ValidateMTU(*opts.MTU); err != nil {
			return nil, fmt.Errorf("invalid MTU: %w", err)
		}
	}

	if opts.LogOutput != nil {
		logrus.SetOutput(opts.LogOutput)
	}

	if opts.LogLevel != "" {
		level, err := logrus.ParseLevel(opts.LogLevel)
		if err != nil {
			return nil, fmt.Errorf("parse log level: %w", err)
		}
		logrus.SetLevel(level)
	}

	if !opts.NoUserspace {
		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)
		}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Use one of: panic, fatal, error, warn, warning, info, debug, trace.
  2. Validate with logrus.ParseLevel before calling embed.New when the string comes from user input or config files.
  3. Leave LogLevel empty to keep the default (info).

Example fix

// before
client, err := embed.New(embed.Options{LogLevel: cfg.LogLevel})

// after
if _, perr := logrus.ParseLevel(cfg.LogLevel); cfg.LogLevel != "" && perr != nil {
    return fmt.Errorf("bad log level %q: %w", cfg.LogLevel, perr)
}
client, err := embed.New(embed.Options{LogLevel: cfg.LogLevel})
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/sirupsen/logrus"

if opts.LogLevel != "" {
    if _, err := logrus.ParseLevel(opts.LogLevel); err != nil {
        return fmt.Errorf("invalid log level %q: %w", opts.LogLevel, err)
    }
}

Prevention

When it happens

Trigger: Calling embed.New with LogLevel set to values like "verbose", "err", "WARN " (trailing space), "INFO" works but "informational", or an empty-ish string like " ".

Common situations: Passing a level name from a different logging library (zap: "dpanic"; slog: "WARN" is fine but slog numeric levels are not); reading the level from an env var that is unset-but-not-empty; typo or case mistakes are tolerated but any unknown word fails.

Related errors


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