apache/beam · error · java.lang.IllegalArgumentException

Invalid hexadecimal Snowflake binary value.

Error message

Invalid hexadecimal Snowflake binary value.

What it means

decodeHex converts a Snowflake binary value given as a hexadecimal string into bytes. If the hex string has an odd number of characters it cannot map to whole bytes, so it immediately throws an IllegalArgumentException.

Solutions

  1. Regenerate/export the value ensuring even-length hex (e.g. HEX_ENCODE with correct settings).
  2. Left-pad the hex string with a leading '0' if the odd length is due to a dropped leading zero.
  3. Catch IllegalArgumentException around toRow and route the bad row to a dead-letter path.

Example fix

// before
byte[] bytes = toRow(new String[]{"abc"}, schema); // odd-length hex
// after
byte[] bytes = toRow(new String[]{"0abc"}, schema); // padded to even length
Defensive patterns

Strategy: validation

Validate before calling

if (value == null || value.length() % 2 != 0 || !value.matches("[0-9a-fA-F]+")) {
  throw new IllegalArgumentException("not valid hex: " + value);
}

Try / catch

try { Row r = SnowflakeSchemaTransformUtils.toRow(parts, schema); }
catch (IllegalArgumentException e) { deadLetter(parts, e); }

Prevention

When it happens

Trigger: A BYTES-typed field whose Snowflake value is a hex string with odd length (e.g. "abc"), typically from truncated or hand-edited values.

Common situations: Truncated hex during export/copy; manual data edits dropping a character; misconfigured export that strips leading zeros.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/2ce3676383d0a900. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/SnowflakeSchemaTransformUtils.java:272

        case ITERABLE:
        case MAP:
        case ROW:
        case LOGICAL_TYPE:
        default:
          throw unsupportedFieldType(field, null);
      }
    } catch (IllegalArgumentException e) {
      throw new IllegalArgumentException(
          String.format(
              "Unable to parse value '%s' as %s for Snowflake field '%s'.",
              value, field.getType().getTypeName(), field.getName()),
          e);
    }
  }

  private static byte[] decodeHex(String value) {
    if ((value.length() & 1) != 0) {
      throw new IllegalArgumentException("Invalid hexadecimal Snowflake binary value.");
    }

    byte[] result = new byte[value.length() / 2];

    for (int i = 0; i < value.length(); i += 2) {
      int high = Character.digit(value.charAt(i), 16);
      int low = Character.digit(value.charAt(i + 1), 16);

      if (high == -1 || low == -1) {
        throw new IllegalArgumentException("Invalid hexadecimal Snowflake binary value.");
      }

      result[i / 2] = (byte) ((high << 4) | low);
    }

    return result;
  }

View on GitHub (pinned to 12126d8942)