elastic/elasticsearch · error · IllegalArgumentException

Can't write raw bytes whose xcontent-type can't be guessed

Error message

Can't write raw bytes whose xcontent-type can't be guessed

What it means

writeRawField(name, content) buffers the input and asks XContentFactory.xContentType(content) to sniff the format by magic bytes / structure. If sniffing returns null (the bytes do not look like JSON, Smile, YAML, or CBOR), it throws IllegalArgumentException because the generator cannot route the bytes to the correct sub-format.

Source

Thrown at libs/x-content/impl/src/main/java/org/elasticsearch/xcontent/provider/json/JsonXContentGenerator.java:474

    public void writeEndRaw() {
        assert base != null : "JsonGenerator should be of instance GeneratorBase but was: " + generator.getClass();
        if (base != null) {
            JsonStreamContext context = base.getOutputContext();
            assert (context instanceof JsonWriteContext) : "Expected an instance of JsonWriteContext but was: " + context.getClass();
            ((JsonWriteContext) context).writeValue();
        }
    }

    @Override
    public void writeRawField(String name, InputStream content) throws IOException {
        if (content.markSupported() == false) {
            // needed for the XContentFactory.xContentType call
            content = new BufferedInputStream(content);
        }
        XContentType contentType = XContentFactory.xContentType(content);
        if (contentType == null) {
            throw new IllegalArgumentException("Can't write raw bytes whose xcontent-type can't be guessed");
        }
        writeRawField(name, content, contentType);
    }

    @Override
    public void writeRawField(String name, InputStream content, XContentType contentType) throws IOException {
        if (mayWriteRawData(contentType) == false) {
            try (XContentParser parser = XContentFactory.xContent(contentType).createParser(XContentParserConfiguration.EMPTY, content)) {
                parser.nextToken();
                writeFieldName(name);
                copyCurrentStructure(parser);
            }
        } else {
            writeStartRaw(name);
            flush();
            Streams.copy(content, os);
            writeEndRaw();
        }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Use the explicit-type overload writeRawField(name, content, XContentType) and pass the type you know
  2. Ensure the bytes are valid JSON (or another supported x-content format) before calling the sniffing overload
  3. Do not call writeRawField with non-x-content binary; use writeBinary instead

Example fix

// before
generator.writeRawField("payload", new ByteArrayInputStream(bytes)); // type unknown -> throws
// after
generator.writeRawField("payload", new ByteArrayInputStream(bytes), XContentType.JSON);
Defensive patterns

Strategy: validation

Validate before calling

XContentType type = XContentFactory.xContentType(content);
if (type == null) {
    throw new IllegalArgumentException("Cannot sniff xcontent type of raw field " + name);
}
generator.writeRawField(name, content, type);

Type guard

static boolean isKnownXContent(InputStream in) {
    if (!in.markSupported()) return false;
    in.mark(1024);
    try { return XContentFactory.xContentType(in) != null; }
    finally { try { in.reset(); } catch (IOException ignored) {} }
}

Try / catch

try { generator.writeRawField(name, content); }
catch (IllegalArgumentException e) { /* use typed overload or writeBinary */ }

Prevention

When it happens

Trigger: Calling jsonGenerator.writeRawField(name, inputStream) where the stream contents are not parseable as any known x-content type. The stream must support mark/reset (it is wrapped in BufferedInputStream if not).

Common situations: Passing plain text, base64, or arbitrary binary as a raw field; passing JSON with the BOM or whitespace stripped such that sniffing fails; the InputStream is empty or already drained; mixing x-content types when the generator only supports JSON (the JSON generator delegates non-JSON content through a parser copy, but it still needs to recognise the source type).

Related errors


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