apache/hadoop · error · IllegalArgumentException
Wrong length: {hex.length}
Error message
Wrong length: {hex.length} What it means
Thrown by MD5Hash.setDigest(String) (and the MD5Hash(String) constructor that delegates to it) when the hex string is not exactly MD5_LEN*2 = 32 characters. MD5 renders as 32 hex digits; any other length — 40 (SHA-1), 64 (SHA-256), base64 text, or text with extra characters — is rejected with IllegalArgumentException before any parsing happens.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/MD5Hash.java:285
/** Returns a string representation of this object. */
@Override
public String toString() {
StringBuilder buf = new StringBuilder(MD5_LEN*2);
for (int i = 0; i < MD5_LEN; i++) {
int b = digest[i];
buf.append(HEX_DIGITS[(b >> 4) & 0xf])
.append(HEX_DIGITS[b & 0xf]);
}
return buf.toString();
}
/**
* Sets the digest value from a hex string.
* @param hex hex.
*/
public void setDigest(String hex) {
if (hex.length() != MD5_LEN*2)
throw new IllegalArgumentException("Wrong length: " + hex.length());
byte[] digest = new byte[MD5_LEN];
for (int i = 0; i < MD5_LEN; i++) {
int j = i << 1;
digest[i] = (byte)(charToNibble(hex.charAt(j)) << 4 |
charToNibble(hex.charAt(j+1)));
}
this.digest = digest;
}
private static final int charToNibble(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'a' && c <= 'f') {
return 0xa + (c - 'a');
} else if (c >= 'A' && c <= 'F') {
return 0xA + (c - 'A');
} else {
throw new RuntimeException("Not a hex character: " + c);View on GitHub (pinned to 2add963021)
Solutions
- Split and trim checksum-file lines: take the first whitespace-delimited token before constructing MD5Hash.
- Confirm the source algorithm is MD5 (32 hex chars); if not, use the matching representation instead of MD5Hash.
- Decode base64 to 16 bytes and use MD5Hash(byte[]) if that is the actual encoding.
- Validate with a regex before calling setDigest to fail with a clearer message (see validation code).
Example fix
// before: whole line passed, length != 32
String line = new String(Files.readAllBytes(md5File)).trim();
new MD5Hash(line); // throws: line includes the filename
// after: extract just the hash token
String hash = line.split("\\s+")[0].trim();
MD5Hash md5 = new MD5Hash(hash); Defensive patterns
Strategy: validation
Validate before calling
String h = raw.trim().split("\\s+")[0]; // strip filename from checksum-file lines
if (!h.matches("[0-9a-fA-F]{32}")) {
throw new IllegalArgumentException("Not an MD5 hex string: '" + raw + "'");
}
new MD5Hash(h); Type guard
static boolean isMd5Hex(String s) {
return s != null && s.matches("[0-9a-fA-F]{32}");
} Prevention
- Checksum-file lines are '<hash> <path>' — split on whitespace and take the first token.
- Pre-validate length AND characters with one regex before calling setDigest.
- Don't feed base64 digests to MD5Hash(String) — decode to bytes and use MD5Hash(byte[]) instead.
When it happens
Trigger: new MD5Hash(hex) or setDigest(hex) with a checksum string from another algorithm, a base64-encoded digest, or a value with whitespace/quotes/newline attached (e.g. a line read from a checksum file that wasn't trimmed).
Common situations: Parsing .md5 checksum files whose format is '<hash> <filename>' without splitting off the filename; mixing up MD5 and SHA checksums in tooling; copy-pasting digests with trailing newline from a terminal; storing digests base64-encoded and passing them raw.
Related errors
- Wrong length: {digest.length}
- Not a hex character: {c}
- Invalid MD5 file {}: the content "{}" does not match the exp
- blockSize should be a multiple of checksumsize
- Bytes per checksum must be greater than 0
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/072ed70d9832fc02.
Report an issue: GitHub.