openfaas/faas · warning

Error reading request body

Error message

Error reading request body

What it means

The scale handler in gateway/scaling/ranges.go requires r.Body to be non-nil and returns 400 'Error reading request body' otherwise. Go's net/http server always supplies a non-nil body for inbound requests, so production clients cannot trigger this branch — an empty body passes here and fails later at JSON unmarshal. It is defensive code that mainly fires in unit tests and handcrafted handlers.

Source

Thrown at gateway/scaling/ranges.go:42

	// MinScaleLabel label indicating min scale for a function
	MinScaleLabel = "com.openfaas.scale.min"

	// MaxScaleLabel label indicating max scale for a function
	MaxScaleLabel = "com.openfaas.scale.max"

	// ScalingFactorLabel label indicates the scaling factor for a function
	ScalingFactorLabel = "com.openfaas.scale.factor"
)

func MakeHorizontalScalingHandler(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Error(w, "Only POST is allowed", http.StatusMethodNotAllowed)
			return
		}

		if r.Body == nil {
			http.Error(w, "Error reading request body", http.StatusBadRequest)
			return
		}

		body, err := io.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "Error reading request body", http.StatusBadRequest)
			return
		}

		scaleRequest := types.ScaleServiceRequest{}
		if err := json.Unmarshal(body, &scaleRequest); err != nil {
			http.Error(w, "Error unmarshalling request body", http.StatusBadRequest)
			return
		}

		if scaleRequest.Replicas < 1 {
			scaleRequest.Replicas = 1
		}

View on GitHub (pinned to 8d803bf9e2)

Solutions

  1. Always send a JSON body — even {} is valid and replicas clamps to 1
  2. In tests, build requests with http.NewRequest(http.MethodPost, url, bytes.NewReader(body))
  3. Ensure no intermediary strips request bodies before they reach the gateway

Example fix

// before (unit test)
req := httptest.NewRequest(http.MethodPost, "/system/scale-function/fn", nil)

// after
req := httptest.NewRequest(http.MethodPost, "/system/scale-function/fn",
    strings.NewReader(`{"replicas":3}`))
Defensive patterns

Strategy: validation

Validate before calling

// always attach a body reader before calling the scale endpoint
if body == nil {
    body = []byte("{}") // valid: replicas clamps to 1
}
req, _ := http.NewRequest(http.MethodPost, scaleURL, bytes.NewReader(body))

Prevention

When it happens

Trigger: Unit tests invoking the handler with a zero-value http.Request (nil Body); custom server plumbing constructing requests without bodies; direct handler invocation in tooling.

Common situations: Writing table-driven tests for the scale handler and passing &http.Request{} directly instead of building the request with http.NewRequest or httptest.NewRequest.

Related errors


AI-assisted analysis of openfaas/faas@8d803bf9e2 (2026-08-16). Data as JSON: /api/errors/b283f67e0b3a4ff0. Report an issue: GitHub.