{"record":{"id":"d8218c4fa9919eb4","repo":"cayleygraph/cayley","slug":"request-is-too-large-d8218c","errorCode":null,"errorMessage":"request is too large","messagePattern":"request is too large","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/http/api_v2.go","lineNumber":489,"sourceCode":"\tw.Write([]byte(`{\"error\": `))\n\tw.Write(data)\n\tw.Write([]byte(\"}\\n\"))\n}\n\nfunc writeResults(w io.Writer, r interface{}) {\n\tenc := json.NewEncoder(w)\n\tenc.SetEscapeHTML(false)\n\tenc.Encode(map[string]interface{}{\n\t\t\"result\": r,\n\t})\n}\n\nconst maxQuerySize = 1024 * 1024 // 1 MB\nfunc readLimit(r io.Reader) ([]byte, error) {\n\tlr := io.LimitReader(r, maxQuerySize).(*io.LimitedReader)\n\tdata, err := ioutil.ReadAll(lr)\n\tif err != nil && lr.N <= 0 {\n\t\terr = errors.New(\"request is too large\")\n\t}\n\treturn data, err\n}\n\n// ServeQuery executes a query received in the request and responds with the result\nfunc (api *APIv2) ServeQuery(w http.ResponseWriter, r *http.Request) {\n\tctx, cancel := api.queryContext(r)\n\tdefer cancel()\n\tvals := r.URL.Query()\n\tlang := vals.Get(\"lang\")\n\tif lang == \"\" {\n\t\tjsonResponse(w, http.StatusBadRequest, \"query language not specified\")\n\t\treturn\n\t}\n\tl := query.GetLanguage(lang)\n\tif l == nil {\n\t\tjsonResponse(w, http.StatusBadRequest, \"unknown query language\")\n\t\treturn","sourceCodeStart":471,"sourceCodeEnd":507,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/server/http/api_v2.go#L471-L507","documentation":"readLimit reads a request body through an io.LimitedReader capped at maxQuerySize (1 MB). When ReadAll stops because the limit was reached, the reader's remaining count lr.N drops to zero and the original read error is replaced with this explicit \"request is too large\" error. It guards ServeQuery against unbounded query payloads so a client cannot exhaust server memory.","triggerScenarios":"POSTing or GETting a query to the /v2/query endpoint whose body exceeds 1 MB (maxQuerySize), so io.LimitReader truncates the read and lr.N <= 0.","commonSituations":"Sending very large Gremlin/Gizmo scripts or huge inline JSON query payloads; batch-generated queries with inlined data lists; clients unaware of the 1 MB request cap.","solutions":["Reduce the query size: remove inlined literals/data and split the work into multiple smaller queries.","Reference large datasets by stored node values/IDs instead of embedding the data in the query body.","If larger queries are genuinely required, raise maxQuerySize in server/http/api_v2.go and redeploy (accepting higher memory usage).","Check the client for accidental payload duplication (e.g. sending the whole dataset in the body)."],"exampleFix":"// before: entire dataset inlined in query body\n{\"gremlin\": \"g.AddV([ /* 5000 inline values... */ ])\", ...}\n// after: store data first, query by reference\n// POST /v2/writes with the data, then a small query:\n{\"gremlin\": \"g.V().HasLabel('target')\"}","handlingStrategy":"validation","validationCode":"// Go client\nif len(queryBody) > 1024*1024 {\n    return fmt.Errorf(\"query body is %d bytes; limit is 1 MB\", len(queryBody))\n}\n// JS client\nif new Blob([body]).size > 1024 * 1024) throw new Error(\"query exceeds 1 MB limit\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check payload size client-side before POSTing queries.","Split large data-heavy queries into writes plus small queries.","Never inline bulk datasets into query strings."],"tags":["http","request-size","limit"],"backgroundTag":"payload-too-large","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}