uber-go/zap · error
malformed request body: %v
Error message
malformed request body: %v
What it means
decodePutJSON parses the JSON body of a PUT request to zap's HTTP level handler and returns this error when the body cannot be decoded as JSON. The underlying decoder error is wrapped into the message. It indicates the request payload is not valid JSON for the expected shape {"level": ...}.
Source
Thrown at http_handler.go:137
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")
}
return *pld.Level, nil
}
View on GitHub (pinned to bbd4ecbd87)
Solutions
- Send a valid JSON body, e.g. curl -X PUT -d '{"level":"info"}' http://host:port/log/level.
- Set the Content-Type: application/json header on the request.
- Validate the JSON payload client-side (e.g. json.Valid in Go or JSON.parse in JS) before sending.
Example fix
// before
curl -X PUT http://localhost:8080/log/level -d 'level=debug'
// after
curl -X PUT http://localhost:8080/log/level -H 'Content-Type: application/json' -d '{"level":"debug"}' Defensive patterns
Strategy: validation
Validate before calling
body, _ := io.ReadAll(resp)
if !json.Valid(body) {
return fmt.Errorf("invalid JSON payload for /log/level")
} Try / catch
resp, err := http.Put(url, "application/json", strings.NewReader(`{"level":"info"}`))
if err != nil || resp.StatusCode != http.StatusOK {
// read body and inspect 'malformed request body' before retrying
} Prevention
- Always send Content-Type: application/json with a JSON object body
- Validate payloads with json.Valid or JSON.parse before sending
- Use a typed client wrapper that marshals a struct instead of hand-built strings
When it happens
Trigger: Sending a PUT request to the /log/level endpoint with an empty body, non-JSON content (e.g. form-encoded or plain text), or syntactically invalid JSON such as 'level=debug' without quotes.
Common situations: curl calls without -H 'Content-Type: application/json' and without a properly quoted JSON body; automation scripts using key=value syntax; truncation of large bodies by proxies.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- must specify logging level
- missing Level
- no encoder name specified
- missing EncodeTime in EncoderConfig
- can't register a sink factory for empty string
AI-assisted analysis of uber-go/zap@bbd4ecbd87 (2026-08-31).
Data as JSON: /api/errors/9cd661f1b75f6de5.
Report an issue: GitHub.