{"record":{"id":"e7434c5e72d681b4","repo":"netbirdio/netbird","slug":"init-log-w-e7434c","errorCode":null,"errorMessage":"init log: %w","messagePattern":"init log: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/ssh.go","lineNumber":149,"sourceCode":"\nfunc sshFn(cmd *cobra.Command, args []string) error {\n\tfor _, arg := range args {\n\t\tif arg == \"-h\" || arg == \"--help\" {\n\t\t\treturn cmd.Help()\n\t\t}\n\t}\n\n\tSetFlagsFromEnvVars(rootCmd)\n\tSetFlagsFromEnvVars(cmd)\n\n\tcmd.SetOut(cmd.OutOrStdout())\n\n\tlogOutput := \"console\"\n\tif firstLogFile := util.FindFirstLogPath(logFiles); firstLogFile != \"\" && firstLogFile != defaultLogFile {\n\t\tlogOutput = firstLogFile\n\t}\n\tif err := util.InitLog(logLevel, logOutput); err != nil {\n\t\treturn fmt.Errorf(\"init log: %w\", err)\n\t}\n\n\tctx := internal.CtxInitState(cmd.Context())\n\n\tsig := make(chan os.Signal, 1)\n\tsignal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)\n\tsshctx, cancel := context.WithCancel(ctx)\n\n\terrCh := make(chan error, 1)\n\tgo func() {\n\t\tif err := runSSH(sshctx, host, cmd); err != nil {\n\t\t\terrCh <- err\n\t\t}\n\t\tcancel()\n\t}()\n\n\tselect {\n\tcase <-sig:","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/ssh.go#L131-L167","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nLOG_LVL=\"verbose\" netbird ssh --log-level \"$LOG_LVL\" peer1\n# -> init log: invalid log level\n\n# after\nnetbird ssh --log-level debug peer1","handlingStrategy":"validation","validationCode":"// validate level + output before the CLI call\nvar validLevels = map[string]bool{\"panic\":true,\"fatal\":true,\"error\":true,\"warn\":true,\"info\":true,\"debug\":true,\"trace\":true}\nif lvl := os.Getenv(\"NB_SSH_LOG_LEVEL\"); lvl != \"\" && !validLevels[lvl] {\n\tlog.Fatalf(\"unsupported --log-level %q\", lvl)\n}\nif lf := os.Getenv(\"NB_SSH_LOG_FILE\"); lf != \"\" {\n\tif _, err := os.Stat(filepath.Dir(lf)); err != nil {\n\t\tlog.Fatalf(\"log dir missing: %v\", err)\n\t}\n}","typeGuard":"func isValidLogLevel(s string) bool {\n\tswitch s {\n\tcase \"panic\", \"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\":\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"if err := util.InitLog(logLevel, logOutput); err != nil {\n\t// classify: unrecognized level vs unwritable sink; the first is a flag typo,\n\t// the second a filesystem/permission issue — print the offending value\n\tfmt.Fprintf(os.Stderr, \"logging init failed for level=%q output=%q: %v\\n\", logLevel, logOutput, err)\n\treturn err\n}","preventionTips":["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."],"tags":["go","cli","logging","configuration"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}