nats-io/nats-server · error · JSInvalidJSONError
JS_INVALID_JSON
JS_INVALID_JSON
Error message
consumer group not specified
What it means
A JSON validation error reported via NewJSInvalidJSONError (code JS_INVALID_JSON) in the distributed consumer-group (durable group) request handler: the request decoded fine but req.Group is empty, and a consumer group name is mandatory for this API. It is intentionally surfaced as an invalid-JSON/invalid-request style error to the client.
Source
Thrown at server/jetstream_api.go:3863
return
}
}
if errorOnRequiredApiLevel(hdr) {
resp.Error = NewJSRequiredApiLevelError()
s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
return
}
var req JSApiConsumerUnpinRequest
if err := json.Unmarshal(msg, &req); err != nil {
resp.Error = NewJSInvalidJSONError(err)
s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
return
}
if req.Group == _EMPTY_ {
resp.Error = NewJSInvalidJSONError(errors.New("consumer group not specified"))
s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
return
}
if !validGroupName.MatchString(req.Group) {
resp.Error = NewJSConsumerInvalidGroupNameError()
s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
return
}
if hasJS, doErr := acc.checkJetStream(); !hasJS {
if doErr {
resp.Error = NewJSNotEnabledForAccountError()
s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
}
return
}
View on GitHub (pinned to 3a66a489d2)
Solutions
- Add a non-empty "group" field to the request JSON.
- Fix JSON field tags/serialization so the group name actually populates req.Group.
- Validate the group name client-side (non-empty, matches validGroupName) before sending.
- Check templating/env substitution that may inject an empty group value.
Example fix
// before
{"stream": "ORDERS", "deliver_subject": "out.orders"} // missing group
// after
{"stream": "ORDERS", "group": "workers", "deliver_subject": "out.orders"} Defensive patterns
Strategy: validation
Validate before calling
type groupReq struct {
Stream string `json:"stream"`
Group string `json:"group"`
}
func validateGroupReq(b []byte) error {
var r groupReq
if err := json.Unmarshal(b, &r); err != nil { return err }
if r.Group == "" { return errors.New("consumer group not specified") }
if !regexp.MustCompile(`^[^ *>$]+$`).MatchString(r.Group) { return errors.New("invalid group name") }
return nil
}
Try / catch
resp, err := nc.Request(subj, body, timeout)
if err != nil { return err }
var apiResp JSApiResponse
json.Unmarshal(resp.Data, &apiResp)
if apiResp.Error != nil && apiResp.Error.Code == 400 /* JS_INVALID_JSON */ {
return fmt.Errorf("bad request: %s", apiResp.Error.Description)
} Prevention
- Always include a non-empty group field in consumer-group requests
- Verify JSON struct tags match the API's expected field names
- Check template/CI variables for empty substitutions
- Validate group names client-side before sending
When it happens
Trigger: Posting a request to the consumer group API ($JS.API.CONSUMER.GROUP style endpoint, handler near jetstream_api.go:3863) with a JSON body lacking the "group" field or containing an empty string; the check `req.Group == _EMPTY_` fires before group-name validation.
Common situations: Omitting the group field in hand-written JSON; struct field tags mismatched so Group never deserializes; empty config values from template/CI variable substitution producing "".
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- unknown consumer action: %v
- unknown priority policy: %v
- got corrupted escaped character
- incomplete type, value pair
- DN ended with incomplete type, value pair
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/f4f1e3f42102257f.
Report an issue: GitHub.