apache/hadoop · error · ParseException
Unexpected end of block
Error message
Unexpected end of block
What it means
CountersStrings.getBlock() parses pre-0.21 compact counter strings shaped 'GROUP*(counter=value)(counter=value)...': after consuming an opening '(' it scans for the matching ')' honoring backslash escapes. If the string ends before the closing paren is found, parsing aborts with ParseException 'Unexpected end of block'.
Source
Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/util/CountersStrings.java:193
// sequences. Throws ParseException if an incomplete block is found else
// returns null.
private static String getBlock(String str, char open, char close,
IntWritable index) throws ParseException {
StringBuilder split = new StringBuilder();
int next = StringUtils.findNext(str, open, StringUtils.ESCAPE_CHAR,
index.get(), split);
split.setLength(0); // clear the buffer
if (next >= 0) {
++next; // move over '('
next = StringUtils.findNext(str, close, StringUtils.ESCAPE_CHAR,
next, split);
if (next >= 0) {
++next; // move over ')'
index.set(next);
return split.toString(); // found a block
} else {
throw new ParseException("Unexpected end of block", next);
}
}
return null; // found nothing
}
/**
* Parse a pre 0.21 counters string into a counter object.
* @param <C> type of the counter
* @param <G> type of the counter group
* @param <T> type of the counters object
* @param compactString to parse
* @param counters an empty counters object to hold the result
* @return the counters object holding the result
* @throws ParseException
*/
@SuppressWarnings("deprecation")
public static <C extends Counter, G extends CounterGroupBase<C>,
T extends AbstractCounters<C, G>>View on GitHub (pinned to 2add963021)
Solutions
- Escape parentheses in counter/group display names with a backslash (StringUtils.ESCAPE_CHAR) when producing strings.
- Produce strings via Counters.toEscapedCompactString() rather than manual formatting so escaping is handled.
- Validate that every '(' has a matching unescaped ')' before parsing legacy strings.
- If the string is truncated, obtain the full value (increase the storage/column width) before parsing.
Example fix
// before: unescaped paren opens a block that never closes String s = "Gr(oup*(m1=1)"; // after: escape it so the group block parses String s = "Gr\\(oup*(m1=1)";
Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap balance check honoring backslash escapes, before parsing a legacy counters string
static boolean blocksBalanced(String s) {
int depth = 0;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '\\') { i++; } else if (ch == '(') { depth++; } else if (ch == ')') { depth--; }
if (depth < 0) { return false; }
}
return depth == 0;
} Try / catch
catch (org.apache.hadoop.util.StringUtils.ParseException e) { if ("Unexpected end of block".equals(e.getMessage())) { /* input truncated or parens unescaped: log the raw string, skip or repair it */ } else { throw e; } } Prevention
- Produce counters strings only via Counters.toEscapedCompactString().
- Escape parentheses in counter and group display names when constructing strings by hand.
- Do not truncate counters strings in storage before parsing them back.
When it happens
Trigger: Parsing a legacy counters string where a block opens but never closes: a group or counter display name containing an unescaped '(', or a truncated/malformed string passed to the parser.
Common situations: Reading old job history or preserved counters strings; hand-built counter strings (e.g., setDisplay names with parentheses) fed back into the parser; string truncation at a fixed-size boundary before parsing.
Related errors
- Counters are enabled, Reporter cannot be NULL
- Counters version mismatch, expected ${groupFactory.version()
- Unexpected counter group type: ${groupType}
- bad framework group id: ${id}
- bad framework group name: ${name}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/4b08a774a0087c80.
Report an issue: GitHub.