{"record":{"id":"36a081e2603117f1","repo":"pentaho/pentaho-kettle","slug":"invalid-hex-digit-c","errorCode":null,"errorMessage":"invalid hex digit '<c>'.","messagePattern":"invalid hex digit '<c>'\\.","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java","lineNumber":1841,"sourceCode":"\n    // we assume a leading 0 if the length is not even.\n    if ( ( len % 2 ) == 1 ) {\n      evenByte = false;\n    }\n\n    int nibble;\n    int i, j;\n    for ( i = 0, j = 0; i < len; i++ ) {\n      char c = hexString.charAt( i );\n\n      if ( ( c >= '0' ) && ( c <= '9' ) ) {\n        nibble = c - '0';\n      } else if ( ( c >= 'A' ) && ( c <= 'F' ) ) {\n        nibble = c - 'A' + 0x0A;\n      } else if ( ( c >= 'a' ) && ( c <= 'f' ) ) {\n        nibble = c - 'a' + 0x0A;\n      } else {\n        throw new KettleValueException( \"invalid hex digit '\" + c + \"'.\" );\n      }\n\n      if ( evenByte ) {\n        nextByte = ( nibble << 4 );\n      } else {\n        nextByte += nibble;\n        chArray[j] = (char) nextByte;\n        j++;\n      }\n\n      evenByte = !evenByte;\n    }\n    return new String( chArray );\n  }\n\n  /**\n   * Change a string into its hexadecimal representation. E.g. if Value contains string \"a\" afterwards it would contain\n   * value \"0061\".","sourceCodeStart":1823,"sourceCodeEnd":1859,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java#L1823-L1859","documentation":"ValueDataUtil.chopHexToBytes converts a hex string to a byte array and validates every hex nibble character. When a character is outside 0-9, A-F, a-f it throws this KettleValueException naming the offending character, because the input is not a valid hex string (e.g. odd characters, whitespace, or odd-length garbage).","triggerScenarios":"Calling ValueDataUtil.chopHexToBytes(hexString) (used by the HEX string decode path in transformations) where the string contains any character outside [0-9A-Fa-f], such as '0x' prefix, spaces, '-', 'g'-'z', or an embedded separator.","commonSituations":"Decoding a hex value that was copy-pasted with a '0x' prefix or colons/spaces (MAC-address style); a binary column exported with different encoding; uppercase/lowercase confusion is fine, but chars like 'O' vs '0' from OCR/manual entry fail.","solutions":["Inspect the reported character in the message and clean the input string: strip '0x' prefix, spaces, colons, dashes","Validate the string with a regex ^[0-9A-Fa-f]+$ before calling chopHexToBytes","Ensure the string length is even; pad with a leading '0' if odd","Fix the upstream producer so it emits pure hex digits"],"exampleFix":"// before\nbyte[] bytes = ValueDataUtil.chopHexToBytes( hexInput ); // \"0x deadBEEF;\"\n// after\nString clean = hexInput == null ? \"\" : hexInput.replaceAll( \"[^0-9A-Fa-f]\", \"\" );\nif ( clean.length() % 2 == 1 ) clean = \"0\" + clean;\nbyte[] bytes = ValueDataUtil.chopHexToBytes( clean );","handlingStrategy":"validation","validationCode":"if ( hex == null || !hex.matches( \"[0-9A-Fa-f]+\" ) || hex.length() % 2 != 0 ) throw new IllegalArgumentException( \"Invalid hex: \" + hex );","typeGuard":"boolean isHexString( String s ) { return s != null && s.matches( \"[0-9A-Fa-f]+\" ) && s.length() % 2 == 0; }","tryCatchPattern":"try {\n  return ValueDataUtil.chopHexToBytes( hex );\n} catch ( KettleValueException e ) {\n  log.warn( \"Bad hex input '\" + hex + \"' -> \" + e.getMessage() );\n  return hex.replaceAll( \"[^0-9A-Fa-f]\", \"\" ).getBytes(); // fallback cleaning\n}","preventionTips":["Strip '0x' prefixes and separators (spaces, colons, dashes) before decoding","Enforce even length; left-pad odd-length strings with '0'","Validate hex at data-ingestion time, not at decode time","Beware look-alike characters (O vs 0, l vs 1) from manual entry"],"tags":["hex","encoding","kettle"],"backgroundTag":"invalid-argument-format","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}