apache/hadoop · error · UnmanglingError

Unknown entity ref {}

Error message

Unknown entity ref {}

What it means

XMLUtils.unmangleXmlString(str, true) reverses mangleXmlString: it decodes backslash-hex escapes (\hhhh;) and, when decodeEntityRefs is true, exactly the five built-in XML entities " ' & < >. Any other '&...;' sequence falls into the else branch and throws UnmanglingError("Unknown entity ref " + e), because the decoder has no table for other named or numeric character references.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/util/XMLUtils.java:196

    StringBuilder entityRef = null;
    for (int i = 0; i < str.length(); i++) {
      char ch = str.charAt(i);
      if (entityRef != null) {
        entityRef.append(ch);
        if (ch == ';') {
          String e = entityRef.toString();
          if (e.equals("&quot;")) {
            bld.append("\"");
          } else if (e.equals("&apos;")) {
            bld.append("\'");
          } else if (e.equals("&amp;")) {
            bld.append("&");
          } else if (e.equals("&lt;")) {
            bld.append("<");
          } else if (e.equals("&gt;")) {
            bld.append(">");
          } else {
            throw new UnmanglingError("Unknown entity ref " + e);
          }
          entityRef = null;
        }
      } else  if ((slashPosition >= 0) && (slashPosition < NUM_SLASH_POSITIONS)) {
        escapedCp += ch;
        ++slashPosition;
      } else if (slashPosition == NUM_SLASH_POSITIONS) {
        if (ch != ';') {
          throw new UnmanglingError("unterminated code point escape: " +
              "expected semicolon at end.");
        }
        try {
          bld.appendCodePoint(Integer.parseInt(escapedCp, 16));
        } catch (NumberFormatException e) {
          throw new UnmanglingError("error parsing unmangling escape code", e);
        }
        escapedCp = "";
        slashPosition = -1;

View on GitHub (pinned to 2add963021)

Solutions

  1. Pre-decode or strip non-standard entities before unmangling (e.g. replace "&nbsp;" with "\u00A0")
  2. Re-emit the XML using only the five standard entities, or regenerate the fsimage XML with `hdfs oiv -p XML`
  3. If a raw '&' is legitimate text, call unmangleXmlString(s, false) and accept that entity refs stay literal

Example fix

// before
String v = XMLUtils.unmangleXmlString(attr, true); // attr = "a&nbsp;b" -> UnmanglingError

// after
String cleaned = attr.replace("&nbsp;", "\u00A0");
String v = XMLUtils.unmangleXmlString(cleaned, true);
Defensive patterns

Strategy: validation

Validate before calling

static final java.util.Set<String> OK = java.util.Set.of("&quot;", "&apos;", "&amp;", "&lt;", "&gt;");
static final java.util.regex.Pattern ENT = java.util.regex.Pattern.compile("&[a-zA-Z#0-9]+;");
static void checkEntities(String s) {
  java.util.regex.Matcher m = ENT.matcher(s);
  while (m.find()) {
    if (!OK.contains(m.group())) {
      throw new IllegalArgumentException("non-standard entity: " + m.group());
    }
  }
}

Try / catch

try {
  String v = XMLUtils.unmangleXmlString(s, true);
} catch (XMLUtils.UnmanglingError e) {
  // input not produced by mangleXmlString; log and reject the value
}

Prevention

When it happens

Trigger: unmangleXmlString(s, true) on a string containing &nbsp;, &copy;, &#38; or any entity outside the five built-ins — typically a value from an OfflineImageViewer fsimage/XML dump that was post-processed or hand-edited, or a string that never passed through mangleXmlString.

Common situations: Running XML tooling (XSLT, HTML sanitizers, pretty-printers) over fsimage XML dumps that injects HTML entities; round-tripping HDFS XML through editors that auto-escape; feeding raw user text containing '&' sequences into the unmangler.

Related errors


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