netbirdio/netbird · error
init log: %w
Error message
init log: %w
What it means
Returned from the `netbird ssh` PersistentPreRun when util.InitLog fails to initialize the logger with the requested level and output. InitLog parses the --log-level flag value and opens/configures the log output (console or the first existing log file from --log-file); an unrecognized level or an unusable output path makes it return an error that is wrapped here.
Source
Thrown at client/cmd/ssh.go:149
func sshFn(cmd *cobra.Command, args []string) error {
for _, arg := range args {
if arg == "-h" || arg == "--help" {
return cmd.Help()
}
}
SetFlagsFromEnvVars(rootCmd)
SetFlagsFromEnvVars(cmd)
cmd.SetOut(cmd.OutOrStdout())
logOutput := "console"
if firstLogFile := util.FindFirstLogPath(logFiles); firstLogFile != "" && firstLogFile != defaultLogFile {
logOutput = firstLogFile
}
if err := util.InitLog(logLevel, logOutput); err != nil {
return fmt.Errorf("init log: %w", err)
}
ctx := internal.CtxInitState(cmd.Context())
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
sshctx, cancel := context.WithCancel(ctx)
errCh := make(chan error, 1)
go func() {
if err := runSSH(sshctx, host, cmd); err != nil {
errCh <- err
}
cancel()
}()
select {
case <-sig:View on GitHub (pinned to 93e97f4bf1)
Solutions
- Re-run with a supported --log-level value (the standard set: panic/fatal/error/warn/info/debug/trace — e.g., --log-level info).
- Check the shell variable feeding --log-level; empty or misspelled values fail, unset the flag to use the default.
- If you also pass --log-file, point it at a path your user can write, or drop the flag to log to console.
- Verify with `netbird ssh --log-level debug <host>` that the rest of the command proceeds past logging setup.
Example fix
# before LOG_LVL="verbose" netbird ssh --log-level "$LOG_LVL" peer1 # -> init log: invalid log level # after netbird ssh --log-level debug peer1
Defensive patterns
Strategy: validation
Validate before calling
// validate level + output before the CLI call
var validLevels = map[string]bool{"panic":true,"fatal":true,"error":true,"warn":true,"info":true,"debug":true,"trace":true}
if lvl := os.Getenv("NB_SSH_LOG_LEVEL"); lvl != "" && !validLevels[lvl] {
log.Fatalf("unsupported --log-level %q", lvl)
}
if lf := os.Getenv("NB_SSH_LOG_FILE"); lf != "" {
if _, err := os.Stat(filepath.Dir(lf)); err != nil {
log.Fatalf("log dir missing: %v", err)
}
} Type guard
func isValidLogLevel(s string) bool {
switch s {
case "panic", "fatal", "error", "warn", "info", "debug", "trace":
return true
}
return false
} Try / catch
if err := util.InitLog(logLevel, logOutput); err != nil {
// classify: unrecognized level vs unwritable sink; the first is a flag typo,
// the second a filesystem/permission issue — print the offending value
fmt.Fprintf(os.Stderr, "logging init failed for level=%q output=%q: %v\n", logLevel, logOutput, err)
return err
} Prevention
- Pin --log-level to a known constant in scripts; never pass an unvalidated environment variable through.
- Default the variable, don't blank it: ${LOG_LEVEL:-info} instead of $LOG_LEVEL.
- When using --log-file with netbird ssh, choose a user-writable path — the ssh command does not run as the daemon user.
- Test new automation with --log-level debug once, then bake the verified level into the script.
When it happens
Trigger: Running `netbird ssh --log-level <bad>` with a value outside the accepted set (e.g., verbose, high, trace2), or passing --log-file entries whose first resolvable path exists but cannot be opened/appended by the current user. The ssh command runs as a regular user, so daemon-owned log files under the system log dir can trigger permission failures.
Common situations: Copying a --log-level value from older NetBird docs or other tools that use different level names; scripts that pass --log-level=$LOG_LEVEL with an empty or misspelled variable; running ssh with a log file path that only root can write.
Related errors
- failed initializing log %v
- address must be in [unix|tcp|npipe]://[path|host:port|name]
- unsupported daemon address protocol: %v
- artifact private key must be provided via %s environment var
- create SSH proxy: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/e7434c5e72d681b4.
Report an issue: GitHub.