uber-go/zap · warning
must specify logging level
Error message
must specify logging level
What it means
The HTTP log-level handler's PUT /log/level endpoint (URL form mode) requires a `level` form/query value. decodePutURL returns errors.New("must specify logging level") when the `level` parameter is absent or empty before attempting UnmarshalText.
Source
Thrown at http_handler.go:123
w.WriteHeader(http.StatusMethodNotAllowed)
return enc.Encode(errorResponse{
Error: "Only GET and PUT are supported.",
})
}
}
// Decodes incoming PUT requests and returns the requested logging level.
func decodePutRequest(contentType string, r *http.Request) (zapcore.Level, error) {
if contentType == "application/x-www-form-urlencoded" {
return decodePutURL(r)
}
return decodePutJSON(r.Body)
}
func decodePutURL(r *http.Request) (zapcore.Level, error) {
lvl := r.FormValue("level")
if lvl == "" {
return 0, errors.New("must specify logging level")
}
var l zapcore.Level
if err := l.UnmarshalText([]byte(lvl)); err != nil {
return 0, err
}
return l, nil
}
func decodePutJSON(body io.Reader) (zapcore.Level, error) {
var pld struct {
Level *zapcore.Level `json:"level"`
}
if err := json.NewDecoder(body).Decode(&pld); err != nil {
return 0, fmt.Errorf("malformed request body: %v", err)
}
if pld.Level == nil {
return 0, errors.New("must specify logging level")
}View on GitHub (pinned to bbd4ecbd87)
Solutions
- Include the level in the request, e.g. curl -X PUT 'http://host:port/log/level?level=debug' or send form value level=debug
- Use a valid zapcore.Level text value (debug, info, warn, error, dpanic, panic, fatal)
Example fix
// before curl -X PUT http://localhost:8080/log/level // after curl -X PUT 'http://localhost:8080/log/level?level=warn'
Defensive patterns
Strategy: validation
Validate before calling
// client side
if lvl == "" {
return errors.New("level query/form parameter is required")
}
req, _ := http.NewRequest(http.MethodPut, fmt.Sprintf("http://host/log/level?level=%s", url.QueryEscape(lvl)), nil) Try / catch
resp, err := client.Do(req)
if err != nil || resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("set level failed: %s", body)
} Prevention
- Always include ?level=<value> on PUT /log/level requests
- Use valid zapcore.Level text values
- Wrap endpoint calls in a helper that enforces the parameter
When it happens
Trigger: Sending an HTTP PUT to the log-level handler endpoint without a `level` form value or query parameter, e.g. PUT /log/level with no body/params.
Common situations: Scripting level changes via curl and forgetting ?level=warn; proxies stripping query parameters; empty form posts.
Related errors
- missing Level
- no encoder name specified
- missing EncodeTime in EncoderConfig
- can't register a sink factory for empty string
- must start with a letter
AI-assisted analysis of uber-go/zap@bbd4ecbd87 (2026-08-31).
Data as JSON: /api/errors/a8720ec4a11328d5.
Report an issue: GitHub.