alibaba/nacos · critical · NacosException

AI resource {channel} recall exceeded configured candidate l

Error message

AI resource {channel} recall exceeded configured candidate limit {limit}

What it means

A SERVER_ERROR (HTTP 500) from ensureWithinRecallLimit: a search recall channel (vector or keyword) returned more hits than the configured candidate ceiling. The service deliberately requests limit+1 from the repository so that exceeding the limit is detectable; breaching it means the storage/vector index did not honor the LIMIT clause. The ceiling defaults to 10000 and is tunable via nacos.ai.resource.search.max-recall-candidates.

Source

Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/search/AiResourceSearchService.java:344

                maxCandidates + 1));
            ensureWithinRecallLimit(vectorHits, maxCandidates, "vector");
            for (AiResourceSearchHit hit : vectorHits) {
                recordMaxScore(scores, hit);
            }
        }
        List<AiResourceSearchHit> keywordHits = repository.searchChunks(query.getNamespaceId(),
            query.getText(), query.getResourceTypes(), maxCandidates + 1);
        ensureWithinRecallLimit(keywordHits, maxCandidates, "keyword");
        for (AiResourceSearchHit hit : keywordHits) {
            recordMaxScore(scores, hit);
        }
        return scores;
    }
    
    private void ensureWithinRecallLimit(List<AiResourceSearchHit> hits, int limit, String channel)
        throws NacosException {
        if (hits != null && hits.size() > limit) {
            throw new NacosException(NacosException.SERVER_ERROR,
                "AI resource " + channel + " recall exceeded configured candidate limit "
                    + limit);
        }
    }
    
    private List<AiResourceSearchDocument> findDocumentsByIds(Collection<Long> documentIds) {
        if (documentIds == null || documentIds.isEmpty()) {
            return Collections.emptyList();
        }
        List<Long> ids = new ArrayList<>(documentIds);
        List<AiResourceSearchDocument> result = new ArrayList<>();
        for (int offset = 0; offset < ids.size(); offset += DOCUMENT_LOOKUP_BATCH_SIZE) {
            int toIndex = Math.min(offset + DOCUMENT_LOOKUP_BATCH_SIZE, ids.size());
            result.addAll(repository.findEntriesByIds(ids.subList(offset, toIndex)));
        }
        return result;
    }
    

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Check the configured value of nacos.ai.resource.search.max-recall-candidates and raise it if it was set too low.
  2. Inspect the active AiResourceSearchRepository / AiResourceVectorIndex implementation for the configured storage dialect and confirm it applies LIMIT correctly.
  3. If the value is sane and recall still exceeds it, treat it as a defect in the storage/vector plugin and file a bug.
  4. As a stopgap, narrow the query (resourceTypes filter) to reduce recall volume.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Page result = searchService.search(query);
} catch (NacosException e) {
    if (e.getErrCode() == NacosException.SERVER_ERROR
            && e.getErrMsg().contains("recall exceeded configured candidate limit")) {
        // degrade: narrow resourceTypes filter or fall back to keyword-only/empty result
        return degradedSearch(query);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Any search query while the active AiResourceSearchRepository or AiResourceVectorIndex returns an unbounded/larger-than-requested result set, or while max-recall-candidates is set below the real recall volume. Raised for the 'vector' channel when the vector index over-returns and for 'keyword' when the chunk repository over-returns.

Common situations: A new or updated storage-dialect plugin whose LIMIT handling is broken; a vector index implementation changed to return the full top-k set; someone set max-recall-candidates to an absurdly small number; very large corpus plus a broken SQL LIMIT for the dialect.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/74e426408861bb54. Report an issue: GitHub.