elastic/elasticsearch · error · IllegalArgumentException

Illegal character inside unquoted field at {}

Error message

Illegal character inside unquoted field at {}

What it means

Thrown by CsvParser.processUnquoted when it encounters a line feed, carriage return, or the configured quote character inside a field that was not opened with a quote. Per RFC 4180, quotes are only valid at the start of a field; a bare quote mid-field, or an embedded newline in an unquoted field, is illegal. The parser reports the offending character position.

Source

Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/CsvParser.java:117

            } else if (isWhitespace(c)) {
                if (trim) {
                    startIndex++;
                }
            } else {
                state = State.UNQUOTED;
                builder.setLength(0);
                return false;
            }
        }
        return true;
    }

    private boolean processUnquoted() {
        int spaceCount = 0;
        for (; currentIndex < length; currentIndex++) {
            char c = currentChar();
            if (c == LF || c == CR || c == quote) {
                throw new IllegalArgumentException("Illegal character inside unquoted field at " + currentIndex);
            } else if (c == separator) {
                state = State.START;
                if (setField(currentIndex - spaceCount)) {
                    return true;
                }
                startIndex = currentIndex + 1;
                return false;
            } else if (trim && isWhitespace(c)) {
                spaceCount++;
            } else {
                spaceCount = 0;
            }
        }
        return false;
    }

    private void processQuoted() {
        for (; currentIndex < length; currentIndex++) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Configure the upstream producer to quote any field containing the quote char, newline, or separator.
  2. Set up a multiline codec so quoted fields spanning newlines are reassembled before the csv processor.
  3. Pre-process the field with a gsub processor to escape or strip stray quote characters if the producer cannot be changed.
  4. Quarantine via on_failure for manual review.

Example fix

// before - producer emits: abc"def,123  (bare quote in unquoted field)
{"csv": {"field": "message", "target_fields": ["name","id"]}}
// after - strip stray quotes then parse
{"gsub": {"field": "message", "pattern": "(?m)(?<=^|,)\"(?![^"]*,(?![^"]*\"))", "replacement": "'"}},
{"csv": {"field": "message", "target_fields": ["name","id"]}}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check that no unquoted field contains a quote or newline before the csv processor:
{"script": {"source": "if (ctx.message =~ /(^|,)[^\"]*[^\",][\"\r\n]/) { throw new Exception('illegal char in unquoted field'); }"}}

Try / catch

{"on_failure": [{"index": {"index": "csv-dlq"}}]}

Prevention

When it happens

Trigger: An unquoted CSV field contains a literal quote character (e.g. value=ab"cd), or the line was split mid-record so a newline appears inside what should be a quoted field. Triggered for each offending character at the printed index.

Common situations: Producers that don't quote fields containing quote characters; multiline records split by a filebeat/multiline codec; CSV export tools that escape quotes by backslash instead of doubling them; field values with embedded CR/LF (Windows line endings) not wrapped in quotes.

Related errors


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