elastic/elasticsearch · error · IllegalArgumentException
No encoder found for media type [{}]
Error message
No encoder found for media type [{}] What it means
Thrown by CustomMustacheFactory.createEncoder() when the requested media type (content type) is not in the ENCODERS map. The factory supports exactly five media types: 'application/json; charset=UTF-8', 'application/json;charset=utf-8', 'application/json', 'text/plain', and 'application/x-www-form-urlencoded'. Any other value passed via the content_type script option triggers this exception.
Source
Thrown at modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomMustacheFactory.java:106
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();
}
private static class CustomMustacheVisitor extends DefaultMustacheVisitor {
CustomMustacheVisitor(DefaultMustacheFactory df) {
super(df);
}View on GitHub (pinned to db6a809a66)
Solutions
- Use one of the five supported content types: 'application/json', 'application/json; charset=UTF-8', 'application/json;charset=utf-8', 'text/plain', or 'application/x-www-form-urlencoded'
- If you don't need a specific content type, omit the content_type option entirely — it defaults to 'application/json'
- For URL-encoded query parameter output, use 'application/x-www-form-urlencoded'
- For plain text passthrough without JSON escaping, use 'text/plain'
Example fix
// before — search template request with unsupported content type:
POST /_search/template
{
"source": { "query": { "match": { "title": "{{q}}" } } },
"params": { "q": "test" },
"content_type": "application/xml"
}
// after — use a supported content type or omit it:
POST /_search/template
{
"source": { "query": { "match": { "title": "{{q}}" } } },
"params": { "q": "test" },
"content_type": "text/plain"
} Defensive patterns
Strategy: validation
Validate before calling
// Validate content_type before submitting search template
Set<String> VALID_CONTENT_TYPES = Set.of(
"application/json",
"application/json; charset=UTF-8",
"application/json;charset=utf-8",
"text/plain",
"application/x-www-form-urlencoded"
);
if (contentType != null && !VALID_CONTENT_TYPES.contains(contentType)) {
throw new IllegalArgumentException("Unsupported content type: " + contentType);
} Prevention
- Default content type is application/json — omit the option if unsure
- Keep the five valid content types in a shared constant
- Document the supported content types in your client library
When it happens
Trigger: Executing a search template with the 'content_type' option set to an unsupported value. For example: {"source": {...}, "params": {...}} with script options specifying a content type like 'application/xml' or 'text/csv'. The option is read from Script.CONTENT_TYPE_OPTION in MustacheScriptEngine.createMustacheFactory() and passed to the builder.
Common situations: Passing a custom or wrong MIME type in the content_type option. Using 'application/xml' or 'application/yaml' which are not supported. Typing the content type incorrectly (e.g., 'application/jason'). Copying a content type from a different API that supports more formats.
Related errors
- Mustache script result size limit exceeded
- Unable to encode value
- 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/e340d4fa5885cc5a.
Report an issue: GitHub.