redis/jedis · error · JedisException
Failed to initialize aggregation cursor
Error message
Failed to initialize aggregation cursor
What it means
Wraps failures from the initial FT.AGGREGATE ... WITHCURSOR invocation in initializeAggregation. If the command cannot be executed (connectivity, auth, bad index, malformed arguments) or the reply cannot be built into an AggregationResult with cursor, this JedisException is thrown during iterator construction.
Solutions
- Verify the search index exists (FT.INFO indexName) and the RediSearch module is loaded
- Check credentials/ACL permissions for FT.AGGREGATE
- Test connectivity to the shard with a simple PING/FT._LIST before iterating
- Catch JedisException at construction and inspect the cause for the server-side error message
Example fix
// before
AggregateIterator it = new AggregateIterator(provider, "idx", aggr); // throws on bad index
// after
try {
AggregateIterator it = new AggregateIterator(provider, "idx", aggr);
} catch (JedisException e) {
log.error("Aggregation init failed: {}", e.getCause() == null ? e : e.getCause().getMessage());
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-checks before constructing the iterator
try (Jedis j = pool.getResource()) { j.ping(); }
// and verify the index exists:
// provider-level FT.INFO indexName must succeed Type guard
null
Try / catch
try {
AggregateIterator it = new AggregateIterator(provider, indexName, aggr);
} catch (JedisException e) {
// init failed: bad index, auth/ACL, module missing, or connectivity
log.error("Aggregation init failed", e.getCause());
} Prevention
- Verify the index exists with FT.INFO before aggregating
- Confirm RediSearch module is loaded and the user's ACL allows FT.AGGREGATE
- Smoke-test connectivity to the target shard before heavy queries
- Include the index name and cause in application error logs
When it happens
Trigger: Creating AggregateIterator when the index does not exist, credentials are wrong, the connection cannot be established, or the aggregation builder produces arguments the server rejects.
Common situations: Typo in index name; FT.AGGREGATE unavailable (RediSearch module not loaded); ACL denying the user the aggregate command; network misconfiguration to the selected shard.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- No connections available from connection provider
- Failed to fetch next aggregation batch
- cursor must be set
- No more aggregation results available
- is not supported.
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/90045ef10451f35f.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/search/aggr/AggregateIterator.java:213
.build(rawReply);
cursorId = result.getCursorId();
return result;
}
/**
* Initializes the aggregation by executing the initial FT.AGGREGATE command.
*/
private void initializeAggregation(AggregationBuilder aggregationBuilder) {
CommandArguments args = new CommandArguments(SearchProtocol.SearchCommand.AGGREGATE)
.add(indexName).addParams(aggregationBuilder);
try {
Object rawReply = executeCommand(args);
aggrCommandResult = AggregationResult.SEARCH_AGGREGATION_RESULT_WITH_CURSOR.build(rawReply);
cursorId = aggrCommandResult.getCursorId();
} catch (Exception e) {
throw new JedisException("Failed to initialize aggregation cursor", e);
}
}
/**
* Executes a command using the connection entry. If the entry value is a Pool, borrows a
* connection, executes the command, and returns the connection to the pool. This pattern prevents
* connection pool exhaustion during long-running aggregation operations.
*/
@SuppressWarnings("unchecked")
private Object executeCommand(CommandArguments args) {
Object entryValue = connectionEntry.getValue();
if (entryValue instanceof Connection) {
// Direct connection (non-pooled) - use directly
return ((Connection) entryValue).executeCommand(args);
} else if (entryValue instanceof Pool) {
// Pooled connection - borrow, use, and return
try (Connection conn = ((Pool<Connection>) entryValue).getResource()) {View on GitHub (pinned to 6dac31d4c2)