apache/dubbo · error · IllegalArgumentException

hex string format error [${c}].

Error message

hex string format error [${c}].

What it means

Thrown by the private hex(char) helper (Bytes.java:866) when a character is not a valid hex digit (outside '0'-'9', 'a'-'f', 'A'-'F'). It is reachable through the public Bytes.hex2bytes(String) and hex2bytes(String, int, int) methods: after those validate parity and bounds, they iterate the string and call hex() per character, so any non-hex char surfaces as IllegalArgumentException with the offending character in the message.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java:876

     *
     * @param is input stream.
     * @return MD5 byte array.
     */
    public static byte[] getMD5(InputStream is) throws IOException {
        return getMD5(is, 1024 * 8);
    }

    private static byte hex(char c) {
        if (c <= '9') {
            return (byte) (c - '0');
        }
        if (c >= 'a' && c <= 'f') {
            return (byte) (c - 'a' + 10);
        }
        if (c >= 'A' && c <= 'F') {
            return (byte) (c - 'A' + 10);
        }
        throw new IllegalArgumentException("hex string format error [" + c + "].");
    }

    private static int indexOf(char[] cs, char c) {
        for (int i = 0, len = cs.length; i < len; i++) {
            if (cs[i] == c) {
                return i;
            }
        }
        return -1;
    }

    private static byte[] decodeTable(String code) {
        int hash = code.hashCode();
        byte[] ret = DECODE_TABLE_MAP.get(hash);
        if (ret == null) {
            if (code.length() < 64) {
                throw new IllegalArgumentException("Base64 code length < 64.");
            }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Strip separators and prefixes before decoding: str = str.replaceAll("[^0-9A-Fa-f]", "").
  2. Remove a leading '0x' if present: if (str.startsWith("0x")) str = str.substring(2);
  3. Validate with a regex first so you control the error message: if (!str.matches("[0-9A-Fa-f]*")) ... (note hex2bytes also requires even length).

Example fix

// before
byte[] b = Bytes.hex2bytes("de:ad:be:ef"); // ':' is not a hex digit
// after
String clean = "de:ad:be:ef".replace(":", "");
byte[] b = Bytes.hex2bytes(clean);
Defensive patterns

Strategy: validation

Validate before calling

String clean = str.replaceAll("[^0-9A-Fa-f]", "");
if (clean.length() % 2 != 0) throw new IllegalArgumentException("hex length must be even");
byte[] b = Bytes.hex2bytes(clean);

Type guard

static boolean isHexString(String s) {
    return s != null && s.matches("[0-9A-Fa-f]*") && s.length() % 2 == 0;
}

Try / catch

try {
    byte[] b = Bytes.hex2bytes(str);
} catch (IllegalArgumentException e) {
    // non-hex char or odd length — reject the untrusted input
    throw new IllegalArgumentException("invalid hex input", e);
}

Prevention

When it happens

Trigger: Calling Bytes.hex2bytes("48656c6c6f") is fine; calling hex2bytes("48656c6c6g") (note 'g') or hex2bytes("de/ad") (contains '/') triggers it; also hex2bytes on input with whitespace, '0x' prefix, or wrong case region.

Common situations: Hex strings copied with a '0x' prefix or spaces/colons/dashes between bytes; uppercase/lowercase assumed but a non-hex char slipped in; a digest/UUID string with separators passed straight through; truncated nibble.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/8701f4b03121d74e. Report an issue: GitHub.