{"record":{"id":"d2194cd449820a8d","repo":"elastic/elasticsearch","slug":"mustache-script-result-size-limit-exceeded","errorCode":null,"errorMessage":"Mustache script result size limit exceeded","messagePattern":"Mustache script result size limit exceeded","errorType":"validation","errorClass":"ElasticsearchParseException","httpStatus":null,"severity":"error","filePath":"modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MustacheScriptEngine.java","lineNumber":153,"sourceCode":"        /**\n         * @param template the compiled template object wrapper\n         **/\n        MustacheExecutableScript(Mustache template, Map<String, Object> params) {\n            super(params);\n            this.template = template;\n            this.params = params;\n        }\n\n        @Override\n        public String execute() {\n            StringWriter writer = new SizeLimitingStringWriter(sizeLimit);\n            try {\n                template.execute(writer, params);\n            } catch (Exception e) {\n                // size limit exception can appear at several places in the causal list depending on script & context\n                if (ExceptionsHelper.unwrap(e, SizeLimitingStringWriter.SizeLimitExceededException.class) != null) {\n                    // don't log, client problem\n                    throw new ElasticsearchParseException(\"Mustache script result size limit exceeded\", e);\n                }\n                if (shouldLogException(e)) {\n                    logger.error(() -> format(\"Error running %s\", template), e);\n                }\n                throw new GeneralScriptException(\"Error running \" + template, e);\n            }\n            return writer.toString();\n        }\n\n        public boolean shouldLogException(Throwable e) {\n            return e.getCause() != null && e.getCause() instanceof MustacheInvalidParameterException == false;\n        }\n    }\n\n}\n","sourceCodeStart":135,"sourceCodeEnd":169,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MustacheScriptEngine.java#L135-L169","documentation":"Thrown by MustacheExecutableScript.execute() when the rendered template output exceeds the configured size limit (mustache.max_output_size_bytes, default 1mb). The SizeLimitingStringWriter throws SizeLimitExceededException which is detected via ExceptionsHelper.unwrap() anywhere in the causal chain and converted to an ElasticsearchParseException. This is explicitly treated as a client problem and not logged.","triggerScenarios":"Executing a search template whose rendered output (after parameter substitution) exceeds the mustache.max_output_size_bytes limit. Common with templates that loop over large arrays, generate large term queries, or produce verbose JSON. The size limit applies to the final rendered string, not the template source or input params.","commonSituations":"Templates with {{#items}} loops over large arrays. Templates generating many terms clauses from a large parameter list. Default 1mb limit being too small for legitimate large queries. Increasing parameter array sizes without adjusting the output size limit.","solutions":["Reduce the number of items in loop parameters — paginate or batch large parameter arrays","Increase the size limit via cluster setting: PUT /_cluster/settings {\"persistent\": {\"mustache.max_output_size_bytes\": \"5mb\"}}","Simplify the template structure to produce less output per parameter item","If the template generates a terms query with thousands of values, consider using a terms lookup or terms set query instead"],"exampleFix":"// before — cluster default (1mb) too small for large template output:\n// (template rendering fails at runtime)\n\n// after — increase the limit via cluster settings:\nPUT /_cluster/settings\n{\n  \"persistent\": {\n    \"mustache.max_output_size_bytes\": \"5mb\"\n  }\n}","handlingStrategy":"validation","validationCode":"// Estimate rendered output size before execution\nint estimateOutputSize(String template, Map<String, Object> params) {\n    // rough estimate: render to a bounded buffer and check\n    // or estimate based on array param sizes * per-item template expansion\n    int estimated = 0;\n    for (var e : params.entrySet()) {\n        if (e.getValue() instanceof Collection<?> c) {\n            estimated += c.size() * 100; // rough per-item cost\n        }\n    }\n    return estimated;\n}\n// compare against mustache.max_output_size_bytes before executing","typeGuard":null,"tryCatchPattern":"// Catch ElasticsearchParseException for size limit exceeded\ntry {\n    String result = templateExecutable.execute();\n} catch (ElasticsearchParseException e) {\n    if (e.getMessage().contains(\"size limit\")) {\n        // reduce params or increase limit\n        log.warn(\"Template output exceeded size limit, reduce input size or increase mustache.max_output_size_bytes\");\n    }\n    throw e;\n}","preventionTips":["Paginate large array parameters instead of sending all at once","Monitor rendered output sizes for templates with loops","Adjust mustache.max_output_size_bytes cluster setting if legitimate large outputs are expected","Use terms lookup or terms set queries instead of expanding huge arrays in templates"],"tags":["elasticsearch","lang-mustache","size-limit","configuration","template"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}