{"record":{"id":"6d67949101efadf1","repo":"openfaas/faas","slug":"err-error","errorCode":null,"errorMessage":"err.Error()","messagePattern":"err\\.Error\\(\\)","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"gateway/handlers/queue_proxy.go","lineNumber":34,"sourceCode":"\t\"github.com/gorilla/mux\"\n\tftypes \"github.com/openfaas/faas-provider/types\"\n\t\"github.com/openfaas/faas/gateway/metrics\"\n\t\"github.com/openfaas/faas/gateway/pkg/middleware\"\n\n\t\"github.com/openfaas/faas/gateway/scaling\"\n)\n\n// MakeQueuedProxy accepts work onto a queue\nfunc MakeQueuedProxy(metrics metrics.MetricOptions, queuer ftypes.RequestQueuer, pathTransformer middleware.URLPathTransformer, defaultNS string, functionQuery scaling.FunctionQuery) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tvar body []byte\n\t\tif r.Body != nil {\n\t\t\tdefer r.Body.Close()\n\n\t\t\tvar err error\n\t\t\tbody, err = io.ReadAll(r.Body)\n\t\t\tif err != nil {\n\t\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tcallbackURL, err := getCallbackURLHeader(r.Header)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\n\t\tvars := mux.Vars(r)\n\t\tname := vars[\"name\"]\n\n\t\treq := &ftypes.QueueRequest{\n\t\t\tFunction:    name,\n\t\t\tBody:        body,\n\t\t\tMethod:      r.Method,\n\t\t\tQueryString: r.URL.RawQuery,","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/openfaas/faas/blob/8d803bf9e2655aec6a60fd0e25b392839f96af95/gateway/handlers/queue_proxy.go#L16-L52","documentation":"MakeQueuedProxy, which serves POST /async-function/{name}, buffers the whole request body with io.ReadAll before enqueueing. If the read itself fails, the raw Go error text is echoed to the client with status 400. A read failure means the transfer was broken or malformed — the queue has not been contacted yet at this point.","triggerScenarios":"Client disconnects or times out mid-upload; malformed chunked transfer encoding; an intermediary (nginx, Traefik, Istio) resets the connection when a body-size or buffering limit is exceeded; keep-alive connection races.","commonSituations":"Large async payloads exceeding proxy limits (nginx client_max_body_size, Traefik body limits); SDKs with aggressive client timeouts aborting during upload; flaky client networks; custom clients hand-rolling chunked encoding.","solutions":["Retry the invocation — mid-body disconnects are usually transient","Reduce the payload size; async bodies are fully buffered and additionally limited by the queue backend","Raise body-size/buffering limits on any ingress proxy in front of the gateway","Use a standard HTTP client library so chunked encoding and headers are well-formed","Inspect the echoed error text ('unexpected EOF', 'malformed HTTP chunked encoding') to identify the failing layer"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := client.Post(asyncURL, contentType, bytes.NewReader(body))\nif err != nil || resp.StatusCode == http.StatusBadRequest {\n    // body transfer was interrupted: replay the buffered body after backoff\n    time.Sleep(backoff)\n    continue\n}","preventionTips":["Send async payloads from an in-memory buffer so requests are replayable","Keep async bodies small — they are fully buffered and also limited by the queue backend","Tune or disable request-body size limits on proxies in front of the gateway"],"tags":["http","request-body","async","go"],"backgroundTag":null,"analyzedSha":"8d803bf9e2655aec6a60fd0e25b392839f96af95","analyzedAt":"2026-08-16T00:12:29.759Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}