hashicorp/nomad · error
Unknown log level
Error message
Unknown log level
What it means
Nomad's agent HTTP 'monitor' streaming endpoint validates the requested log level before attaching a log sink. The requested LogLevel string is passed to log.LevelFromString; if it does not parse to a recognized hclog level, the result is log.NoLevel and the endpoint aborts the stream with this 400 error. It exists to fail fast with a clear message instead of silently falling back to a default level.
Source
Thrown at client/agent_endpoint.go:109
return
}
// Check acl
if aclObj, err := a.c.ResolveToken(args.AuthToken); err != nil {
handleStreamResultError(err, new(int64(403)), encoder)
return
} else if !aclObj.AllowAgentRead() {
handleStreamResultError(structs.ErrPermissionDenied, new(int64(403)), encoder)
return
}
logLevel := log.LevelFromString(args.LogLevel)
if args.LogLevel == "" {
logLevel = log.LevelFromString("INFO")
}
if logLevel == log.NoLevel {
handleStreamResultError(errors.New("Unknown log level"), new(int64(400)), encoder)
return
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
m := monitor.New(512, a.c.logger, &log.LoggerOptions{
JSONFormat: args.LogJSON,
Level: logLevel,
IncludeLocation: args.LogIncludeLocation,
})
frames := make(chan *sframer.StreamFrame, streamFramesBuffer)
errCh := make(chan error)
var buf bytes.Buffer
frameCodec := codec.NewEncoder(&buf, structs.JsonHandle)
framer := sframer.NewStreamFramer(frames, 1*time.Second, 200*time.Millisecond, 1024)View on GitHub (pinned to 482b49bf1a)
Solutions
- Set log_level to one of TRACE, DEBUG, INFO, WARN, ERROR (case-insensitive) on the monitor request
- Omit log_level entirely to default to INFO
- Fix the caller/CLI wrapper so it maps friendly level names to hclog-valid levels
- Validate the level client-side before issuing the request
Example fix
// before GET /v1/agent/monitor?log_level=warning // after GET /v1/agent/monitor?log_level=WARN
Defensive patterns
Strategy: validation
Validate before calling
validLevels := map[string]bool{"trace":true,"debug":true,"info":true,"warn":true,"error":true}
if logLevel != "" && !validLevels[strings.ToLower(logLevel)] {
return fmt.Errorf("invalid log_level %q; must be TRACE|DEBUG|INFO|WARN|ERROR", logLevel)
} Type guard
func isValidLogLevel(s string) bool {
return s == "" || log.LevelFromString(s) != log.NoLevel
} Try / catch
// Go: check the HTTP response before streaming
resp, err := c.Raw(agent.MonitorQuery{LogLevel: lvl})
if err != nil {
if strings.Contains(err.Error(), "Unknown log level") {
lvl = "INFO"
return c.Raw(agent.MonitorQuery{LogLevel: lvl})
}
return err
} Prevention
- Use hclog's level constants/names instead of free-form strings
- Validate log level flags in CLI wrappers before calling the API
- Omit log_level rather than sending an empty-ish placeholder
When it happens
Trigger: Calling the Agent Monitor API (GET /v1/agent/monitor) with query/log_level set to a string that is not one of TRACE, DEBUG, INFO, WARN, ERROR (case-insensitive), e.g. 'verbose', 'warning', 'all', or a typo like 'INF0'. An empty string is explicitly allowed (defaults to INFO).
Common situations: Hand-built HTTP requests or CLI wrappers passing an invalid --log-level flag; UI clients mapping user-chosen levels to wrong strings; automation scripts using 'warning' instead of 'WARN'.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Nomad Enterprise only endpoint
- missing policy name
- No nomad log file defined
- command is not present
- Unknown log level
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/16f458610dc29042.
Report an issue: GitHub.