elastic/elasticsearch · error · IllegalArgumentException

maxConcurrentSearchRequests must be positive

Error message

maxConcurrentSearchRequests must be positive

What it means

Thrown by MultiSearchTemplateRequest.maxConcurrentSearchRequests(int) when the provided value is less than 1. This setter validates that the concurrency level is a positive integer because zero or negative concurrency would mean no search requests can execute. The value is typically set from the 'max_concurrent_searches' URL parameter in _msearch/template.

Source

Thrown at modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MultiSearchTemplateRequest.java:87

     */
    public MultiSearchTemplateRequest add(SearchTemplateRequest request) {
        requests.add(request);
        return this;
    }

    /**
     * Returns the amount of search requests specified in this multi search requests are allowed to be ran concurrently.
     */
    public int maxConcurrentSearchRequests() {
        return maxConcurrentSearchRequests;
    }

    /**
     * Sets how many search requests specified in this multi search requests are allowed to be ran concurrently.
     */
    public MultiSearchTemplateRequest maxConcurrentSearchRequests(int maxConcurrentSearchRequests) {
        if (maxConcurrentSearchRequests < 1) {
            throw new IllegalArgumentException("maxConcurrentSearchRequests must be positive");
        }

        this.maxConcurrentSearchRequests = maxConcurrentSearchRequests;
        return this;
    }

    public List<SearchTemplateRequest> requests() {
        return this.requests;
    }

    @Override
    public ActionRequestValidationException validate() {
        ActionRequestValidationException validationException = null;
        if (requests.isEmpty()) {
            validationException = addValidationError("no requests added", validationException);
        }
        for (SearchTemplateRequest request : requests) {
            ActionRequestValidationException ex = request.validate();

View on GitHub (pinned to db6a809a66)

Solutions

  1. Set max_concurrent_searches to a positive integer (1 or greater): ?max_concurrent_searches=5
  2. If you want Elasticsearch to decide concurrency, omit the parameter entirely rather than setting it to 0
  3. In client code, validate the value before passing: if (value < 1) skip the setter call
  4. Use a reasonable default based on your cluster size, e.g., 5 or 10 for moderate workloads

Example fix

// before — zero concurrency:
POST /_msearch/template?max_concurrent_searches=0

// after — positive value or omit entirely:
POST /_msearch/template?max_concurrent_searches=5
Defensive patterns

Strategy: validation

Validate before calling

// Validate max_concurrent_searches before building the request
int maxConcurrent = clientConfig.getMaxConcurrentSearches();
if (maxConcurrent < 1) {
    // omit the parameter or use a sensible default
    maxConcurrent = 5; // or skip setting it
}
request.maxConcurrentSearchRequests(maxConcurrent);

Prevention

When it happens

Trigger: Sending a _msearch/template request with ?max_concurrent_searches=0 or a negative value. Also triggered by programmatically calling multiSearchTemplateRequest.maxConcurrentSearchRequests(0) or maxConcurrentSearchRequests(-1). The parseRequest method in RestMultiSearchTemplateAction reads the parameter via restRequest.paramAsInt("max_concurrent_searches", 0) and passes it to this setter.

Common situations: Passing max_concurrent_searches=0 expecting it to mean 'unlimited' or 'default'. Using a default value of 0 in client code without checking. Misunderstanding that the value must be >= 1. Configuring via a UI or config file that allows zero.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/e137833212fa02f4. Report an issue: GitHub.