dgraph-io/dgraph · error
Exceeded query edge limit = %v. Found %v edges.
Error message
Exceeded query edge limit = %v. Found %v edges.
What it means
Dgraph's shortest-path / k-shortest-path query walks edges breadth-first and aborts once the number of traversed edges exceeds the query edge limit (Config.LimitQueryEdge), a safety cap preventing unbounded graph exploration from exhausting memory/CPU. Note the message reports the mutated-nquads config value (LimitMutationsNquad) instead of LimitQueryEdge — a known cosmetic bug — but the enforced limit is the edge limit. The query is cancelled and this error returned to the client.
Source
Thrown at query/shortest.go:233
return
}
// TODO - This simplify overrides the adjacency matrix. What happens if the
// cost along the second attribute is more than that along the first.
adjacencyMap[fromUID][toUID] = mapItem{
cost: cost,
facet: facet,
attr: subgraph.Attr,
}
numEdges++
}
}
}
}
if numEdges > x.Config.LimitQueryEdge {
// If we've seen too many edges, stop the query.
rch <- errors.Errorf("Exceeded query edge limit = %v. Found %v edges.",
x.Config.LimitMutationsNquad, numEdges)
return
}
// modify the exec and attach child nodes.
var out []*SubGraph
for _, subgraph := range exec {
if len(subgraph.DestUIDs.Uids) == 0 {
continue
}
select {
case <-ctx.Done():
rch <- ctx.Err()
return
default:
for _, child := range sg.Children {
temp := new(SubGraph)
temp.copyFiltersRecurse(child)View on GitHub (pinned to 759e242be6)
Solutions
- Reduce traversal breadth: use `limit` / stronger predicates in the `from`/`to` blocks and on intermediate hops so fewer edges are expanded.
- Raise the server limit: increase --query_edge (LimitQueryEdge) in Dgraph's configuration and restart Alpha.
- Narrow the query: pin down intermediate nodes or use n-depth paths to constrain the search space.
- Split the query: run the shortest path between closer endpoints or compute in stages in application code.
Example fix
// before (DQL)
{ q(func: uid(0x1)) { shortest(to: uid(0x2)) { friend } } }
// after: constrain expansion
{ q(func: uid(0x1)) {
shortest(to: uid(0x2), numpaths: 1) {
friend @filter(gt(since, "2020-01-01"))
}
}
} Defensive patterns
Strategy: validation
Validate before calling
// Before issuing a shortest-path query, estimate breadth and cap hops
const q = `{ q(func: uid(${from})) { shortest(to: uid(${to}), depth: ${depth}) { friend } } }`;
if (depth > 5) throw new Error('depth too large for query_edge limit');
await dgraph.NewTxn().Query(ctx, q); Try / catch
try {
await txn.Query(ctx, shortestPathQuery);
} catch (e) {
if (String(e).includes('Exceeded query edge limit')) {
// retry with tighter filters/lower depth or raise --query_edge
}
throw e;
} Prevention
- Add @filter and limit clauses inside shortest-path blocks to bound expansion
- Keep --query_edge sized to your graph's fan-out; monitor for this error as a capacity signal
- Prefer numpaths: 1 unless k paths are truly needed
- Split long-range path queries into staged hops
When it happens
Trigger: Running a shortest/k-shortest path query (from/to with a `shortest` block) whose exploration touches more edges than allowed by the --query_edge limit (LimitQueryEdge in Config), e.g. a broad graph expansion before the destination is found.
Common situations: Shortest-path queries over highly connected graphs (social graphs, massive fan-out at intermediate hops); default or reduced --query_edge limits in production; a typo'd or very distant `to` node causing wide traversal; running with graph_path/limit directives that expand many edges per hop.
Related errors
- from/to can't be nil for shortest path
- value of from var(%s) should have already been populated
- from variable(%s) should only expand to 1 uid
- value of to var(%s) should have already been populated
- to variable(%s) should only expand to 1 uid
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/06ef5146ca894e3b.
Report an issue: GitHub.