{"record":{"id":"094561cb13ed98d6","repo":"elastic/elasticsearch","slug":"illegal-escape-sequence","errorCode":null,"errorMessage":"Illegal escape sequence '\\{}'","messagePattern":"Illegal escape sequence '\\\\(.+?)'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/CefParser.java","lineNumber":394,"sourceCode":"            }\n        }\n        for (; i < extensionString.length(); i++) {\n            char curr = extensionString.charAt(i);\n            char next = i < extensionString.length() - 1 ? extensionString.charAt(i + 1) : '\\0';\n\n            if (curr == '\\\\') {\n                if (next == '\\\\') { // an escaped backslash\n                    buffer.append('\\\\'); // emit a backslash\n                } else if (next == '=') { // an escaped equals\n                    buffer.append('='); // emit an equals\n                } else if (next == 'n') { // a 'newline'\n                    buffer.append('\\n'); // emit a newline\n                } else if (next == 'r') { // a 'carriage return'\n                    buffer.append('\\r'); // emit a carriage return\n                } else if (next == 't') { // a 'tab' -- the spec doesn't actually mention \\t being escaped into a tab, but we do it anyway\n                    buffer.append('\\t'); // emit a tab\n                } else {\n                    throw new IllegalArgumentException(\"Illegal escape sequence '\\\\\" + next + \"'\"); // TODO gross on \\n, for example ugh\n                }\n                i++; // and skip the next character\n            } else if (curr == '=') { // an equals, it's the end of a chunk\n                chunks.add(buffer.toString()); // emit the chunk\n                buffer = new StringBuilder(); // and reset the buffer\n            } else { // any other character\n                buffer.append(curr); // is just added to the current thing\n            }\n        }\n        chunks.add(buffer.toString()); // don't forget the ragged-edge last chunk ;)\n\n        if (chunks.size() == 1) {\n            String chunk = chunks.getFirst();\n            if (chunk.isEmpty()) {\n                return Map.of();\n            } else {\n                throw new IllegalArgumentException(\"Invalid extensions in the CEF event: \" + chunk);\n            }","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/CefParser.java#L376-L412","documentation":"Thrown by CefParser.parseExtensions while scanning a CEF event's extension section. CEF permits only five backslash escapes (\\\\, \\=, \\n, \\r, \\t); any backslash immediately followed by a different character — or by end-of-string — is rejected. The exception propagates out of CefProcessor.execute and fails the ingest document.","triggerScenarios":"A CEF extension string containing a backslash before an unsupported character — e.g. a Windows path 'C:\\Windows' (yields '\\W'), a regex '\\d+', a literal '\\u0000', or a trailing '\\' at the final position of the string. Calling CefParser.process on such a line throws immediately during parseExtensions.","commonSituations":"Ingesting syslog/CEF feeds from security products (IPS/EDR) whose payload contains Windows file paths, registry keys, or regex text that the producer did not CEF-escape. Also seen after a forwarder strips or rewrites backslashes, and when test fixtures are authored without doubling backslashes.","solutions":["Sanitize the source value before the cef processor: replace each '\\' that is not followed by one of \\,=,n,r,t with '\\\\' (double-escape) using a script/grok pre-processor.","Strip or trim a trailing lone backslash from the field before it reaches the cef processor.","Attach an on_failure pipeline to the cef processor and route the failing document there instead of failing the bulk request.","If escaping cannot be fixed upstream, file an issue with the CEF producer — its data is not spec-compliant."],"exampleFix":"// before — value carries an unescaped Windows path\n//  field: 'CEF:0|vendor|prod|1.0|100|test|3|suser=C:\\\\Windows\\\\system32'\n//  -> parseExtensions sees '\\\\W' and throws.\n//\n// after — pre-escape backslashes in a script processor so each '\\' becomes '\\\\'\n{\n  \"script\": {\n    \"source\": \"ctx[params.field] = ctx[params.field].replace(/\\\\(?![\\\\=nrt])/,'\\\\\\\\\\\\\\\\'); \"\n  }\n}","handlingStrategy":"validation","validationCode":"// Reject input that contains a backslash not followed by an allowed escape target.\nprivate static final Pattern BAD_ESCAPE = Pattern.compile(\"\\\\\\\\(?![\\\\\\\\=nrt])\");\nboolean isSafeForCefExtensions(String ext) {\n    return ext == null || !BAD_ESCAPE.matcher(ext).find();\n}","typeGuard":null,"tryCatchPattern":"// Inside an Elasticsearch pipeline — route CEF failures to a quarantine pipeline.\n{\n  \"on_failure\": [\n    { \"set\": { \"field\": \"ingest.error\", \"value\": \"cef-escape\" } },\n    { \"redirect\": { \"pipeline\": \"quarantine\" } }\n  ]\n}","preventionTips":["Treat every '\\' in CEF producer output as suspicious unless explicitly allowed; pre-escape '\\\\' as '\\\\\\\\'.","Add a fixture-based unit test that exercises the CEF escape rules for backslash, equals, n, r, t.","Always configure on_failure on the cef processor in production pipelines."],"tags":["ingest","cef","escape-sequence","parsing"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}