apache/hadoop · error · IllegalArgumentException

Bad HTML quoting for {}

Error message

Bad HTML quoting for {}

What it means

HtmlQuoting.unquoteHtmlChars(String) is the inverse of quoteHtmlChars and only understands the five entities written by this class: & ' > < ". Any other '&...' sequence (for example  , ', or stray text after an ampersand ending in ';') throws IllegalArgumentException naming the offending entity. The class is used by Hadoop's web UI code to round-trip strings it escaped itself; it is not a general-purpose HTML entity decoder.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HtmlQuoting.java:205

        next += 5;
      } else if (item.startsWith("'", next)) {
        buffer.append('\'');
        next += 6;        
      } else if (item.startsWith(">", next)) {
        buffer.append('>');
        next += 4;
      } else if (item.startsWith("<", next)) {
        buffer.append('<');
        next += 4;
      } else if (item.startsWith("&quot;", next)) {
        buffer.append('"');
        next += 6;
      } else {
        int end = item.indexOf(';', next)+1;
        if (end == 0) {
          end = len;
        }
        throw new IllegalArgumentException("Bad HTML quoting for " + 
                                           item.substring(next,end));
      }
      posn = next;
      next = item.indexOf('&', posn);
    }
    buffer.append(item.substring(posn, len));
    return buffer.toString();
  }
  
  public static void main(String[] args) throws Exception {
    for(String arg:args) {
      System.out.println("Original: " + arg);
      String quoted = quoteHtmlChars(arg);
      System.out.println("Quoted: "+ quoted);
      String unquoted = unquoteHtmlChars(quoted);
      System.out.println("Unquoted: " + unquoted);
      System.out.println();
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Only unquote strings that were produced by HtmlQuoting.quoteHtmlChars (or that contain no '&')
  2. Convert numeric references first (e.g. replace('&#39;', "'")) or decode with a full HTML unescaper before calling unquoteHtmlChars
  3. Wrap the call in try-catch IllegalArgumentException and reject/log the raw input when it contains unrecognized entities

Example fix

// before: throws IllegalArgumentException("Bad HTML quoting for &#39;")
String v = HtmlQuoting.unquoteHtmlChars(s);

// after: normalize numeric refs, then unquote
String v = HtmlQuoting.unquoteHtmlChars(
    s.replaceAll("&#(\\d+);", m -> String.valueOf((char) Integer.parseInt(m.group(1)))));
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern OK_ENTITY =
    Pattern.compile("&(amp|apos|gt|lt|quot);");
static boolean isUnquotable(String s) {
  if (s == null || s.indexOf('&') < 0) return true;
  Matcher m = Pattern.compile("&[^;&]*;?").matcher(s);
  while (m.find()) {
    if (!OK_ENTITY.matcher(m.group()).matches()) return false;
  }
  return true;
}

Try / catch

try {
  value = HtmlQuoting.unquoteHtmlChars(raw);
} catch (IllegalArgumentException e) {
  // unknown/numeric entity: reject input or decode with a full unescaper instead
  value = strictDecodeFallback(raw); // or throw a 400 upstream
}

Prevention

When it happens

Trigger: Calling HtmlQuoting.unquoteHtmlChars on input escaped by a different encoder (numeric character references like &#39; are the classic case, since this parser has no '&#' branch); parsing web UI strings that contain named entities Hadoop never emits.

Common situations: Custom tooling that reuses HtmlQuoting to decode form parameters or log lines containing browser-escaped text; feed pipelines that pass arbitrary HTML through Hadoop web helpers.

Related errors


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