{"record":{"id":"072ed70d9832fc02","repo":"apache/hadoop","slug":"wrong-length-hex-length","errorCode":null,"errorMessage":"Wrong length: {hex.length}","messagePattern":"Wrong length: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/MD5Hash.java","lineNumber":285,"sourceCode":"  /** Returns a string representation of this object. */\n  @Override\n  public String toString() {\n    StringBuilder buf = new StringBuilder(MD5_LEN*2);\n    for (int i = 0; i < MD5_LEN; i++) {\n      int b = digest[i];\n      buf.append(HEX_DIGITS[(b >> 4) & 0xf])\n          .append(HEX_DIGITS[b & 0xf]);\n    }\n    return buf.toString();\n  }\n\n  /**\n   * Sets the digest value from a hex string.\n   * @param hex hex.\n   */\n  public void setDigest(String hex) {\n    if (hex.length() != MD5_LEN*2)\n      throw new IllegalArgumentException(\"Wrong length: \" + hex.length());\n    byte[] digest = new byte[MD5_LEN];\n    for (int i = 0; i < MD5_LEN; i++) {\n      int j = i << 1;\n      digest[i] = (byte)(charToNibble(hex.charAt(j)) << 4 |\n                         charToNibble(hex.charAt(j+1)));\n    }\n    this.digest = digest;\n  }\n\n  private static final int charToNibble(char c) {\n    if (c >= '0' && c <= '9') {\n      return c - '0';\n    } else if (c >= 'a' && c <= 'f') {\n      return 0xa + (c - 'a');\n    } else if (c >= 'A' && c <= 'F') {\n      return 0xA + (c - 'A');\n    } else {\n      throw new RuntimeException(\"Not a hex character: \" + c);","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/MD5Hash.java#L267-L303","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"// before: whole line passed, length != 32\nString line = new String(Files.readAllBytes(md5File)).trim();\nnew MD5Hash(line); // throws: line includes the filename\n\n// after: extract just the hash token\nString hash = line.split(\"\\\\s+\")[0].trim();\nMD5Hash md5 = new MD5Hash(hash);","handlingStrategy":"validation","validationCode":"String h = raw.trim().split(\"\\\\s+\")[0]; // strip filename from checksum-file lines\nif (!h.matches(\"[0-9a-fA-F]{32}\")) {\n  throw new IllegalArgumentException(\"Not an MD5 hex string: '\" + raw + \"'\");\n}\nnew MD5Hash(h);","typeGuard":"static boolean isMd5Hex(String s) {\n  return s != null && s.matches(\"[0-9a-fA-F]{32}\");\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["md5","checksum","validation","hadoop-common"],"backgroundTag":"digest-length-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}