elastic/elasticsearch · error · MustacheException
Unable to encode value
Error message
Unable to encode value
What it means
Thrown by CustomMustacheFactory.encode() when the configured encoder fails to write an encoded value due to an IOException. This is a low-level wrapper that catches I/O failures from the underlying Writer during template rendering and converts them into a MustacheException. The encoder itself (JsonEscapeEncoder, UrlEncoder, or DefaultEncoder) does not typically throw, so the IOException usually originates from the downstream Writer being closed or the output stream failing.
Source
Thrown at modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomMustacheFactory.java:99
* @deprecated Use {@link #builder()} instead to retrieve a {@link Builder} object that can be used to create a factory.
*/
@Deprecated
public CustomMustacheFactory() {
this(DEFAULT_MEDIA_TYPE, DEFAULT_DETECT_MISSING_PARAMS);
}
private CustomMustacheFactory(String mediaType, boolean detectMissingParams) {
super(resourceName -> null); // we do not resolve templates via files or the classpath, etc.
setObjectHandler(new CustomReflectionObjectHandler(detectMissingParams));
this.encoder = createEncoder(mediaType);
}
@Override
public void encode(String value, Writer writer) {
try {
encoder.encode(value, writer);
} catch (IOException e) {
throw new MustacheException("Unable to encode value", e);
}
}
static Encoder createEncoder(String mediaType) {
final Supplier<Encoder> supplier = ENCODERS.get(mediaType);
if (supplier == null) {
throw new IllegalArgumentException("No encoder found for media type [" + mediaType + "]");
}
return supplier.get();
}
@Override
public MustacheVisitor createMustacheVisitor() {
return new CustomMustacheVisitor(this);
}
public static Builder builder() {
return new Builder();View on GitHub (pinned to db6a809a66)
Solutions
- Check for size-limit issues first — if mustache.max_output_size_bytes is being hit, the root cause is the size limit, not encoding
- Simplify the template to reduce output volume and retry
- Check server logs for concurrent OOM or stream-closed errors that could explain the I/O failure
- If reproducible, isolate the template parameter values that trigger the error and test them individually
Defensive patterns
Strategy: try-catch
Try / catch
// When executing templates programmatically, catch MustacheException
try {
TemplateScript.Factory factory = engine.compile(...);
String result = factory.newInstance(params).execute();
} catch (MustacheException e) {
// check cause for IOException — often a secondary symptom
log.warn("Template encoding failed: {}", e.getMessage());
} Prevention
- Monitor for size-limit violations which can cascade into encoding errors
- Ensure templates don't produce excessively large output
- Check server memory if encoding errors appear frequently
When it happens
Trigger: Executing a search template (via _search/template or _msearch/template) where template rendering writes to a Writer that encounters an I/O error mid-encode. This can happen when the output buffer is closed prematurely, when the SizeLimitingStringWriter has already thrown, or under memory pressure causing stream failures.
Common situations: Template execution under memory pressure or after a size-limit violation has partially corrupted the writer state. Concurrent use of a shared factory in a way that stresses I/O paths. Rarely seen in normal operation — usually a secondary symptom of another failing condition.
Related errors
- Exception while parsing mustache function at line {tc.line()
- No encoder found for media type [{}]
- Cannot expand '%s' because partial templates are not support
- Cannot expand '%s' because dynamic partial templates are not
- Mustache function [{}] must contain one and only one identif
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/fd3ff590d5853934.
Report an issue: GitHub.