cayleygraph/cayley · error

request is too large

Error message

request is too large

What it means

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.

Source

Thrown at server/http/api_v2.go:489

	w.Write([]byte(`{"error": `))
	w.Write(data)
	w.Write([]byte("}\n"))
}

func writeResults(w io.Writer, r interface{}) {
	enc := json.NewEncoder(w)
	enc.SetEscapeHTML(false)
	enc.Encode(map[string]interface{}{
		"result": r,
	})
}

const maxQuerySize = 1024 * 1024 // 1 MB
func readLimit(r io.Reader) ([]byte, error) {
	lr := io.LimitReader(r, maxQuerySize).(*io.LimitedReader)
	data, err := ioutil.ReadAll(lr)
	if err != nil && lr.N <= 0 {
		err = errors.New("request is too large")
	}
	return data, err
}

// ServeQuery executes a query received in the request and responds with the result
func (api *APIv2) ServeQuery(w http.ResponseWriter, r *http.Request) {
	ctx, cancel := api.queryContext(r)
	defer cancel()
	vals := r.URL.Query()
	lang := vals.Get("lang")
	if lang == "" {
		jsonResponse(w, http.StatusBadRequest, "query language not specified")
		return
	}
	l := query.GetLanguage(lang)
	if l == nil {
		jsonResponse(w, http.StatusBadRequest, "unknown query language")
		return

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Reduce the query size: remove inlined literals/data and split the work into multiple smaller queries.
  2. Reference large datasets by stored node values/IDs instead of embedding the data in the query body.
  3. If larger queries are genuinely required, raise maxQuerySize in server/http/api_v2.go and redeploy (accepting higher memory usage).
  4. Check the client for accidental payload duplication (e.g. sending the whole dataset in the body).

Example fix

// before: entire dataset inlined in query body
{"gremlin": "g.AddV([ /* 5000 inline values... */ ])", ...}
// after: store data first, query by reference
// POST /v2/writes with the data, then a small query:
{"gremlin": "g.V().HasLabel('target')"}
Defensive patterns

Strategy: validation

Validate before calling

// Go client
if len(queryBody) > 1024*1024 {
    return fmt.Errorf("query body is %d bytes; limit is 1 MB", len(queryBody))
}
// JS client
if new Blob([body]).size > 1024 * 1024) throw new Error("query exceeds 1 MB limit");

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06). Data as JSON: /api/errors/d8218c4fa9919eb4. Report an issue: GitHub.