apache/hadoop · error · IllegalArgumentException
Illegal escaped string {} unescaped {} at {}
Error message
Illegal escaped string {} unescaped {} at {} What it means
StringUtils.unEscapeString(str, escapeChar, charsToEscape) processes escape sequences in delimited strings (the standard way Hadoop escapes ',', '=', '\' in Configuration values). It throws IllegalArgumentException when a character follows the escape char but is neither the escape char itself nor in charsToEscape — an escape that unescapes nothing meaningful.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/StringUtils.java:760
* unEscapeString.
* @param str str.
* @param escapeChar escapeChar.
* @param charsToEscape array of characters to unescape
* @return escape string.
*/
public static String unEscapeString(String str, char escapeChar,
char[] charsToEscape) {
if (str == null) {
return null;
}
StringBuilder result = new StringBuilder(str.length());
boolean hasPreEscape = false;
for (int i=0; i<str.length(); i++) {
char curChar = str.charAt(i);
if (hasPreEscape) {
if (curChar != escapeChar && !hasChar(charsToEscape, curChar)) {
// no special char
throw new IllegalArgumentException("Illegal escaped string " + str +
" unescaped " + escapeChar + " at " + (i-1));
}
// otherwise discard the escape char
result.append(curChar);
hasPreEscape = false;
} else {
if (hasChar(charsToEscape, curChar)) {
throw new IllegalArgumentException("Illegal escaped string " + str +
" unescaped " + curChar + " at " + i);
} else if (curChar == escapeChar) {
hasPreEscape = true;
} else {
result.append(curChar);
}
}
}
if (hasPreEscape ) {
throw new IllegalArgumentException("Illegal escaped string " + str + View on GitHub (pinned to 2add963021)
Solutions
- Escape every literal escape char in the input (double backslashes on Windows paths: C:\\tmp)
- Produce values with StringUtils.escapeString(value, escapeChar, sameCharsToEscape) so both sides agree on the format
- Validate/normalize input before unescaping and reject unknown escape sequences with a clear message
- If a trailing sequence keeps failing, prefer comma-separated values parsed with StringSplitter-style APIs that document their escaping
Example fix
// before
String raw = "C:\tmp\\x"; // single backslash: '\t' seen as escaping ordinary 't'
String v = StringUtils.unEscapeString(raw, '\\', new char[]{',', '='});
// after
String raw = "C:\\tmp\\x"; // every literal backslash doubled
String v = StringUtils.unEscapeString(raw, '\\', new char[]{',', '='}); Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidEscaped(String s, char esc, char[] toEscape) {
String specials = new String(toEscape);
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == esc) {
if (i + 1 >= s.length()) return false; // dangling escape
char n = s.charAt(++i);
if (n != esc && specials.indexOf(n) < 0) return false; // escape of ordinary char
} else if (specials.indexOf(c) >= 0) {
return false; // raw special char
}
}
return true;
}
// use: isValidEscaped(value, '\\', new char[]{',', '='}) before unEscapeString Try / catch
try { StringUtils.unEscapeString(str, esc, chars); } catch (IllegalArgumentException e) { /* message prints str, offending char and index — fix escaping at the producer */ } Prevention
- Always create escaped strings with StringUtils.escapeString(value, esc, sameChars) — never hand-escape
- Keep the escape char and charsToEscape set identical on producer and consumer sides
- Double every literal backslash (Windows paths) before embedding values in escaped config strings
- Round-trip test: unEscapeString(escapeString(x)) == x for every value your app writes
When it happens
Trigger: Parsing configuration values where an input like 'a\\z' uses the escape char ('\\') before an ordinary character: Windows paths 'C:\\tmp' passed with single backslashes, or values escaped by different rules than the parser expects.
Common situations: User-supplied config values with stray backslashes; producers that escape a different char set than the consumer's charsToEscape; hand-edited XML values with half-escaped delimiters.
Related errors
- Illegal escaped string {}, not expecting {} in the end.
- Failed to create uri for {}
- Named output '{namedOutput}' already alreadyDefined
- Named output '{namedOutput}' not defined
- No more entry in " + f
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/4714a7451140b7f7.
Report an issue: GitHub.