nats-io/nats-server · warning

Error decoding state for %s

Error message

Error decoding state for %s

What it means

The monitor state decoder cannot map the requested state string to a known connection state (open/closed/any/all). It writes HTTP 400 and returns this error, so the connz/subsz monitoring request is aborted.

Source

Thrown at server/monitor.go:720

	return val, nil
}

func decodeState(w http.ResponseWriter, r *http.Request) (ConnState, error) {
	str := r.URL.Query().Get("state")
	if str == _EMPTY_ {
		return ConnOpen, nil
	}
	switch strings.ToLower(str) {
	case "open":
		return ConnOpen, nil
	case "closed":
		return ConnClosed, nil
	case "any", "all":
		return ConnAll, nil
	}
	// We do not understand intended state here.
	w.WriteHeader(http.StatusBadRequest)
	err := fmt.Errorf("Error decoding state for %s", str)
	w.Write([]byte(err.Error()))
	return 0, err
}

func decodeSubs(w http.ResponseWriter, r *http.Request) (subs bool, subsDet bool, err error) {
	subsDet = strings.ToLower(r.URL.Query().Get("subs")) == "detail"
	if !subsDet {
		subs, err = decodeBool(w, r, "subs")
	}
	return
}

// HandleConnz process HTTP requests for connection information.
func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) {
	sortOpt := SortOpt(r.URL.Query().Get("sort"))
	auth, err := decodeBool(w, r, "auth")
	if err != nil {
		return

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Use one of the accepted values: state=open, state=closed, state=any (or all)
  2. Omit the state parameter entirely to use the default
  3. Validate/whitelist the state parameter in any client or proxy constructing monitoring URLs

Example fix

// before
GET /connz?state=OPEN_CONNECTIONS
// after
GET /connz?state=open
Defensive patterns

Strategy: validation

Validate before calling

var validStates = map[string]bool{"open": true, "closed": true, "any": true, "all": true}
if !validStates[strings.ToLower(state)] {
	return fmt.Errorf("state must be open|closed|any|all, got %q", state)
}

Try / catch

resp, err := http.Get(monitorURL + "/connz?state=" + state)
if err != nil || resp.StatusCode == http.StatusBadRequest {
	return fmt.Errorf("monitoring request rejected (check state param): status=%d err=%v", statusIf(resp), err)
}

Prevention

When it happens

Trigger: Requesting a monitoring endpoint like /connz?state=banana with an unrecognized state value; decodeConnzState receives a str that matches none of open/closed/any/all.

Common situations: Typo in the state query parameter; a client sending a boolean or numeric state; proxy scripts forwarding arbitrary user input into monitoring URLs.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/26eedc27fcc076af. Report an issue: GitHub.