apache/hadoop · error · IllegalArgumentException

Illegal escaped string {}, not expecting {} in the end.

Error message

Illegal escaped string {}, not expecting {} in the end.

What it means

The final check in StringUtils.unEscapeString: after the scan loop, a still-pending escape (hasPreEscape) means the string ends with a dangling escape character that has nothing to unescape. IllegalArgumentException is thrown — the escape grammar cannot terminate on a bare escape char.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/StringUtils.java:778

          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 + 
          ", not expecting " + escapeChar + " in the end." );
    }
    return result.toString();
  }
  
  /**
   * Return a message for logging.
   * @param prefix prefix keyword for the message
   * @param msg content of the message
   * @return a message for logging
   */
  public static String toStartupShutdownString(String prefix, String[] msg) {
    StringBuilder b = new StringBuilder(prefix);
    b.append("\n/************************************************************");
    for(String s : msg)
      b.append("\n").append(prefix).append(s);
    b.append("\n************************************************************/");
    return b.toString();

View on GitHub (pinned to 2add963021)

Solutions

  1. Strip or double a trailing escape char before parsing: if (s.endsWith("\\")) s = s.substring(0, s.length()-1) + "\\\\";
  2. Fix the producer that emits the dangling escape (check join/append loops)
  3. Validate input length and last character early and reject with an actionable message
  4. Round-trip test escapeString/unEscapeString on every value you generate

Example fix

// before
String raw = "path=C:\\tmp\\";  // trailing dangling escape
StringUtils.unEscapeString(raw, '\\', esc);

// after
String raw = "path=C:\\tmp\\\\"; // trailing backslash itself escaped
StringUtils.unEscapeString(raw, '\\', esc);
Defensive patterns

Strategy: validation

Validate before calling

if (str != null && !str.isEmpty() && str.charAt(str.length() - 1) == escapeChar) {
  throw new IllegalArgumentException("Value ends with dangling escape char: '" + str + "'");
}
String v = StringUtils.unEscapeString(str, escapeChar, charsToEscape);

Try / catch

try { StringUtils.unEscapeString(str, esc, chars); } catch (IllegalArgumentException e) { /* trailing escape: strip or double it, then retry */ }

Prevention

When it happens

Trigger: Input like "value\\" — a trailing backslash produced by truncated user input, shell quoting that eats the escaped char, or code that unconditionally appends the escape char when building lists.

Common situations: CLI/shell quoting stripping the character after a backslash; hand-typed config values ending in '\\'; join loops that append esc + delimiter but drop the final delimiter.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/686f74e6606398d9. Report an issue: GitHub.