elastic/elasticsearch · error · XContentParseException
Failed to derive xcontent
Error message
Failed to derive xcontent
What it means
Thrown by the deprecated XContentFactory.xContent(CharSequence) when xContentType(content) returns null, meaning the character sequence does not match the signature of any known XContent format (JSON, YAML, SMILE, CBOR). The method guesses format from leading bytes/characters and fails if no format matches.
Source
Thrown at libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentFactory.java:181
if (Character.isWhitespace(c) == false) {
break;
}
}
return null;
}
/**
* Guesses the content (type) based on the provided char sequence and returns the corresponding {@link XContent}
*
* @deprecated the content type should not be guessed except for few cases where we effectively don't know the content type.
* The REST layer should move to reading the Content-Type header instead. There are other places where auto-detection may be needed.
* This method is deprecated to prevent usages of it from spreading further without specific reasons.
*/
@Deprecated
public static XContent xContent(CharSequence content) {
XContentType type = xContentType(content);
if (type == null) {
throw new XContentParseException("Failed to derive xcontent");
}
return xContent(type);
}
/**
* Guesses the content type based on the provided bytes and returns the corresponding {@link XContent}
*
* @deprecated the content type should not be guessed except for few cases where we effectively don't know the content type.
* The REST layer should move to reading the Content-Type header instead. There are other places where auto-detection may be needed.
* This method is deprecated to prevent usages of it from spreading further without specific reasons.
*/
@Deprecated
public static XContent xContent(byte[] data) {
return xContent(data, 0, data.length);
}
/**
* Guesses the content type based on the provided bytes and returns the corresponding {@link XContent}View on GitHub (pinned to db6a809a66)
Solutions
- Specify the content type explicitly instead of relying on auto-detection (pass XContentType to the parser).
- Ensure the CharSequence is non-empty and starts with a valid format indicator (e.g., '{' or '[' for JSON).
- If the content is binary (SMILE/CBOR), use the byte[] overload, not CharSequence.
- Migrate away from the deprecated xContent(CharSequence) method; read Content-Type from the request header.
Example fix
// before — deprecated auto-detection XContent x = XContentFactory.xContent(charSequence); // after — explicit type from header XContentType type = XContentType.fromMediaType(contentTypeHeader); XContent x = XContentFactory.xContent(type);
Defensive patterns
Strategy: validation
Validate before calling
// Before calling xContent(CharSequence), verify content is non-empty and detectable
public static XContentType detectOrThrow(CharSequence content) {
if (content == null || content.length() == 0 || content.toString().isBlank()) {
throw new IllegalArgumentException("Content is empty, cannot detect type");
}
XContentType type = XContentFactory.xContentType(content);
if (type == null) {
throw new IllegalArgumentException("Content does not match JSON, YAML, SMILE, or CBOR");
}
return type;
} Try / catch
try {
XContent x = XContentFactory.xContent(content);
} catch (XContentParseException e) {
if ("Failed to derive xcontent".equals(e.getMessage())) {
// Fallback: ask caller for explicit content type
throw new IllegalStateException("Cannot detect content type; specify XContentType explicitly", e);
}
throw e;
} Prevention
- Avoid the deprecated xContent(CharSequence) API; pass the known XContentType explicitly.
- Read the Content-Type header and derive XContentType from it instead of guessing.
- Ensure content is non-empty and starts with a recognizable format indicator before auto-detection.
When it happens
Trigger: Passing an empty string, a string with only whitespace, a string whose first non-whitespace character does not match any known format's magic bytes/leading character, or a string containing non-UTF-8 binary data (e.g., SMILE bytes passed as a CharSequence).
Common situations: Auto-detection on empty or whitespace-only bodies. Passing binary SMILE/CBOR content as a string (corrupting it). Receiving garbled input from a malfunctioning upstream service. Using the deprecated xContent(CharSequence) API instead of specifying the content type explicitly.
Related errors
- Cannot guess the xcontent type without mark/reset support on
- Failed to load version properties
- Input does not start with Smile format header
- expected value but got [{token}]
- [{name}] failed to parse object
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/c9c9618f2338aed3.
Report an issue: GitHub.