openfaas/faas · warning

Error writing response after adding metrics

Error message

Error writing response after adding metrics

What it means

After enriching the function list with Prometheus data, AddMetricsHandler re-serializes it with json.Marshal; a marshal failure returns 500 'Error writing response after adding metrics'. Because the data was just produced by unmarshaling provider JSON into plain structs (strings and numbers only), every field is marshal-safe and this branch is effectively unreachable defensive code — hitting it indicates corruption or modified code.

Source

Thrown at gateway/metrics/add_metrics.go:73

		if len(functions) > 0 {

			ns := functions[0].Namespace
			q := fmt.Sprintf(`sum(gateway_function_invocation_total{function_name=~".*.%s"}) by (function_name)`, ns)
			// Restrict query results to only function names matching namespace suffix.

			results, err := prometheusQuery.Fetch(url.QueryEscape(q))
			if err != nil {
				// log the error but continue, the mixIn will correctly handle the empty results.
				log.Printf("Error querying Prometheus: %s\n", err.Error())
			}
			mixIn(&functions, results)
		}

		bytesOut, err := json.Marshal(functions)
		if err != nil {
			log.Printf("Error serializing functions: %s", err)
			http.Error(w, "Error writing response after adding metrics", http.StatusInternalServerError)
			return
		}

		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		w.Write(bytesOut)
	}
}

func mixIn(functions *[]types.FunctionStatus, metrics *VectorQueryResponse) {

	if functions == nil {
		return
	}

	for i, function := range *functions {
		for _, v := range metrics.Data.Result {

View on GitHub (pinned to 8d803bf9e2)

Solutions

  1. Treat occurrences as a bug: capture the gateway log line 'Error serializing functions: ...' which names the marshal error
  2. Check for local patches or forks modifying types.FunctionStatus or mixIn
  3. Retry the request once to rule out transient corruption
  4. Report upstream with the log output if it reproduces on an unmodified gateway
Defensive patterns

Strategy: retry

Try / catch

resp, err := client.Get(gateway + "/system/functions")
if err != nil || resp.StatusCode == http.StatusInternalServerError {
    // practically unreachable server branch: retry once, and capture the
    // gateway log line 'Error serializing functions' for a bug report
    time.Sleep(backoff)
    continue
}

Prevention

When it happens

Trigger: Not reproducible through normal requests: []types.FunctionStatus cannot carry non-marshalable values after a round-trip through json.Unmarshal. Only a patched or forked gateway adding a chan/func/NaN field to FunctionStatus, or altering mixIn, could trigger it.

Common situations: Custom forks extending FunctionStatus or mixIn with unsupported types; memory corruption; reports that almost always turn out to be a nearby, different error.

Related errors


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