dgraph-io/dgraph · error
Couldn't evaluate @normalize directive - too many results
Error message
Couldn't evaluate @normalize directive - too many results
What it means
The @normalize directive flattens and merges result branches into edge-list form. During merge, Dgraph caps total materialized nodes with the LimitNormalizeNode config; exceeding it aborts the query since the response would be unbounded.
Source
Thrown at query/outputnode.go:901
return nn
}
func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) {
if len(parent) == 0 {
return child, nil
}
// Here we merge two slices of maps.
mergedList := make([]fastJsonNode, 0)
cnt := 0
for _, pa := range parent {
for _, ca := range child {
paCopy, paNodeCount := enc.copyFastJsonList(pa)
caCopy, caNodeCount := enc.copyFastJsonList(ca)
cnt += paNodeCount + caNodeCount
if cnt > x.Config.LimitNormalizeNode {
return nil, errors.Errorf(
"Couldn't evaluate @normalize directive - too many results")
}
if paCopy == nil {
paCopy = caCopy
} else {
temp := paCopy
for temp.next != nil {
temp = temp.next
}
temp.next = caCopy
}
mergedList = append(mergedList, paCopy)
}
}
return mergedList, nil
}
View on GitHub (pinned to 759e242be6)
Solutions
- Add tighter filters/pagination (first, offset) to the root or nested blocks to reduce result count
- Raise the limit via --limit and/or the LIMIT_NORMALIZE_NODE option (same name) in Greater Limit options if the result size is genuinely intended
- Restructure the query: split into smaller queries without @normalize, or aggregate instead of returning every edge
- Filter child edges (e.g. @filter(has(...))) so fewer branches are merged per parent
Example fix
// before
{
q(func: type(Person)) @normalize {
name
friend { friendName: name }
}
}
// after
{
q(func: type(Person), first: 1000) @normalize {
name
friend (first: 10) { friendName: name }
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// estimate result size first with a count query
const [{ count }] = await dgraph.query('{ c(func: type(Person)) { count(uid) } }');
if (count * avgFanout > 1_000_000) throw new Error('normalize result would exceed limit; paginate'); Try / catch
try {
return await dgraph.query(q); // q uses @normalize
} catch (e) {
if (String(e).includes('too many results') && /normalize/.test(q)) {
return await dgraph.query(paginate(q)); // retry with first/offset
}
throw e;
} Prevention
- Always pair @normalize with first/offset pagination on the root block
- Cap nested edge expansion with (first: N) inside normalized blocks
- Tune LimitNormalizeNode only after estimating true result size
- Prefer aggregations over full edge lists for analytics queries
When it happens
Trigger: A @normalize query whose combined parent+child lists exceed x.Config.LimitNormalizeNode (default 1e6) — e.g. a broad root match with a nested reverse edge expanded for every node, cross-producting results.
Common situations: Queries on large graphs without filters; @normalize combined with recurse or expand(_all_); instances with default LIMIT_NORMALIZE_NODE config on datasets larger than intended.
Related errors
- while writing to buffer. Encoded response size: %d is bigger
- Wrong type %v encountered for func ln
- Wrong type %v encountered for func exp
- Wrong type %v encountered for func u-
- Wrong type %v encountered for func sqrt
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/be19f15b18c1661d.
Report an issue: GitHub.