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

  1. Verify the search index exists (FT.INFO indexName) and the RediSearch module is loaded
  2. Check credentials/ACL permissions for FT.AGGREGATE
  3. Test connectivity to the shard with a simple PING/FT._LIST before iterating
  4. 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

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


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)