{"record":{"id":"6ca31dcef5a50ed8","repo":"elastic/elasticsearch","slug":"unmatched-quote","errorCode":null,"errorMessage":"Unmatched quote","messagePattern":"Unmatched quote","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/CsvParser.java","lineNumber":81,"sourceCode":"                        return;\n                    }\n                    break;\n                case QUOTED:\n                    processQuoted();\n                    break;\n                case QUOTED_END:\n                    if (processQuotedEnd()) {\n                        return;\n                    }\n                    break;\n            }\n        }\n\n        // we've reached end of string, we need to handle last field\n        switch (state) {\n            case UNQUOTED -> setField(length);\n            case QUOTED_END -> setField(length - 1);\n            case QUOTED -> throw new IllegalArgumentException(\"Unmatched quote\");\n        }\n    }\n\n    private boolean processStart() {\n        for (; currentIndex < length; currentIndex++) {\n            char c = currentChar();\n            if (c == quote) {\n                state = State.QUOTED;\n                builder.setLength(0);\n                startIndex = currentIndex + 1;\n                return false;\n            } else if (c == separator) {\n                startIndex++;\n                builder.setLength(0);\n                if (setField(startIndex)) {\n                    return true;\n                }\n            } else if (isWhitespace(c)) {","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/CsvParser.java#L63-L99","documentation":"Thrown by CsvParser when the input line ends while the state machine is still inside QUOTED state, meaning an opening quote was never matched by a closing quote. The parser reaches end-of-string having never transitioned out of QUOTED, which it treats as malformed CSV. This is a hard parse error from the CsvProcessor's line parser.","triggerScenarios":"A csv processor parses a line where a quoted field opens with the configured quote char but the line is truncated before the closing quote, e.g. value=\"abc with no terminator, or an embedded quote that was not properly escaped/doubled.","commonSituations":"Log shippers splitting multi-line CSV records across lines (CSV fields legitimately contain newlines within quotes); misconfigured quote characters; truncated UDP/syslog payloads; copy-paste artifacts that lost a quote.","solutions":["Verify the configured 'quote' character on the csv processor matches the producer's quoting.","Ensure multi-line quoted records are joined into a single string field before the csv processor runs (use a multiline codec upstream).","Inspect the raw input line for the unclosed quote and fix the producer.","Add an 'on_failure' handler to quarantine malformed records."],"exampleFix":"// before - field delivered line-by-line, quoted field spans lines\n{\"csv\": {\"field\": \"message\", \"target_fields\": [\"a\",\"b\"]}}\n// after - join multiline records first, then parse\n{\"multiline\": {...}},\n{\"csv\": {\"field\": \"message\", \"target_fields\": [\"a\",\"b\"], \"quote\": \"\\\"\"}}","handlingStrategy":"validation","validationCode":"// Ensure the source field is a single complete line before the csv processor by joining multiline records upstream (filebeat multiline codec).\n// In a script processor, you can also pre-check for balanced quotes:\n{\"script\": {\"source\": \"long q = ctx.message.chars().filter(c -> c == '\\\"').count(); if (q % 2 != 0) { throw new Exception('unbalanced quotes'); }\"}}","typeGuard":null,"tryCatchPattern":"{\"on_failure\": [{\"set\": {\"field\": \"failure\", \"value\": \"csv-unmatched-quote\"}}, {\"index\": {\"index\": \"csv-dlq\"}}]}","preventionTips":["Use a multiline codec on the shipper so quoted fields spanning newlines are reassembled.","Confirm the configured quote character matches the producer.","Quarantine malformed records rather than dropping them."],"tags":["ingest","csv-processor","csv-parsing","data-quality"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}