{"record":{"id":"8f88b5fe71a93569","repo":"nsqio/nsq","slug":"invalid-log-level-s-debug-info-warn-error","errorCode":null,"errorMessage":"invalid log level '%s' (debug, info, warn, error, fatal)","messagePattern":"invalid log level '(.+?)' \\(debug, info, warn, error, fatal\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lg/lg.go","lineNumber":73,"sourceCode":"\t\treturn \"FATAL\"\n\t}\n\treturn \"invalid\"\n}\n\nfunc ParseLogLevel(levelstr string) (LogLevel, error) {\n\tswitch strings.ToLower(levelstr) {\n\tcase \"debug\":\n\t\treturn DEBUG, nil\n\tcase \"info\":\n\t\treturn INFO, nil\n\tcase \"warn\":\n\t\treturn WARN, nil\n\tcase \"error\":\n\t\treturn ERROR, nil\n\tcase \"fatal\":\n\t\treturn FATAL, nil\n\t}\n\treturn 0, fmt.Errorf(\"invalid log level '%s' (debug, info, warn, error, fatal)\", levelstr)\n}\n\nfunc Logf(logger Logger, cfgLevel LogLevel, msgLevel LogLevel, f string, args ...interface{}) {\n\tif cfgLevel > msgLevel {\n\t\treturn\n\t}\n\t_ = logger.Output(3, fmt.Sprintf(msgLevel.String()+\": \"+f, args...))\n}\n\nfunc LogFatal(prefix string, f string, args ...interface{}) {\n\tlogger := log.New(os.Stderr, prefix, log.Ldate|log.Ltime|log.Lmicroseconds)\n\tLogf(logger, FATAL, FATAL, f, args...)\n\tos.Exit(1)\n}\n","sourceCodeStart":55,"sourceCodeEnd":88,"githubUrl":"https://github.com/nsqio/nsq/blob/85cf10c09c6c3c86160d6f0eb156f62d0efc1648/internal/lg/lg.go#L55-L88","documentation":"internal/lg/loglevel.go's LevelFromString (internal/lg/lg.go) parses log level strings for every nsq binary's --log-level flag; it accepts only debug, info, warn, error and fatal after lowercasing. Any other value returns 'invalid log level \\'%s\\' ...' listing the valid set, and the binary exits during flag validation before doing any work.","triggerScenarios":"Passing --log-level=warning, --log-level=WARNING is fine (lowercased) but --log-level=err, notice, trace, INFO2, or a value with whitespace/typo (e.g. 'in fo', 'info ') fails. It applies to nsqd, nsqlookupd, nsqadmin, and the apps since they all use internal/lg via their options.","commonSituations":"Copy-pasting log level names from other ecosystems (python 'warning', syslog 'notice', logrus 'trace'); config templating that substitutes an empty or unset variable producing '--log-level=' (empty string is NOT in the switch, so it fails); upgrading scripts where 'warning' was tolerated by an older wrapper.","solutions":["Use exactly one of: debug, info, warn, error, fatal (case-insensitive).","If the level comes from an environment variable that may be unset, default it in the wrapper: --log-level=${LOG_LEVEL:-info}.","Fix 'warning' -> 'warn' and 'err' -> 'error' in configs; these are the two most common near-misses."],"exampleFix":"# before\nnsqd --log-level=warning\n# invalid log level 'warning' (debug, info, warn, error, fatal)\n\n# after\nnsqd --log-level=warn","handlingStrategy":"validation","validationCode":"func isValidLogLevel(s string) bool {\n    switch strings.ToLower(s) {\n    case \"debug\", \"info\", \"warn\", \"error\", \"fatal\":\n        return true\n    }\n    return false\n}\n\nif lvl := os.Getenv(\"NSQ_LOG_LEVEL\"); lvl != \"\" && !isValidLogLevel(lvl) {\n    return fmt.Errorf(\"NSQ_LOG_LEVEL=%q invalid; use debug|info|warn|error|fatal\", lvl)\n}","typeGuard":"func isValidLogLevel(s string) bool {\n    switch strings.ToLower(s) {\n    case \"debug\", \"info\", \"warn\", \"error\", \"fatal\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"// wrapper scripts: catch flag errors and hint the accepted set\nif err := runNsqd(args); err != nil && strings.Contains(err.Error(), \"invalid log level\") {\n    return errors.New(\"set --log-level to one of: debug, info, warn, error, fatal (note: 'warning' is not valid)\")\n}","preventionTips":["Default env-driven levels in wrappers: ${LOG_LEVEL:-info}.","Remember the odd one out is 'warn', not 'warning'.","Lint configs for near-miss level names before deploy."],"tags":["logging","flags","configuration","startup"],"backgroundTag":null,"analyzedSha":"85cf10c09c6c3c86160d6f0eb156f62d0efc1648","analyzedAt":"2026-08-16T00:53:05.009Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}