spring-projects/spring-security · error · IllegalArgumentException

Detected a Non-hex character at N or N+1 position

Error message

Detected a Non-hex character at N or N+1 position

What it means

Hex.decode validates each character pair with Character.digit(c, 16). If either character of a pair is not a hex digit (0-9, a-f, A-F), the library throws IllegalArgumentException identifying the 1-based positions (i+1 or i+2) where the bad character may be. Note both positions of the offending pair are reported since it doesn't say which one failed.

Solutions

  1. Inspect the reported positions and correct the characters to valid hex digits.
  2. Sanitize input first: strip whitespace and validate with hexStr.matches("[0-9a-fA-F]+") before decoding.
  3. Fix the producer to emit proper hex (e.g. String.format("%02x", b)) instead of Base64 or raw chars.

Example fix

// before
byte[] key = Hex.decode(raw.trim()); // may contain 'g' or spaces
// after
String clean = raw.replaceAll("\\s", "");
if (!clean.matches("[0-9a-fA-F]+")) throw new IllegalArgumentException("not hex: " + clean);
byte[] key = Hex.decode(clean);
Defensive patterns

Strategy: validation

Validate before calling

boolean isHex(CharSequence s) { return s != null && s.length() % 2 == 0 && s.chars().allMatch(c -> Character.digit(c, 16) >= 0); }

Try / catch

try { bytes = Hex.decode(s); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Bad hex at/near: " + e.getMessage(), e); }

Prevention

When it happens

Trigger: Calling Hex.decode("zz12") or any string containing 'g'-'z', punctuation, whitespace (e.g. "ab cd"), or unicode characters — even length but non-hex content.

Common situations: Hashes copied from logs with embedded spaces or line breaks; uppercase prefix like "0X"; Base64 data mistakenly treated as hex; locale-dependent case mangling.

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 spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/3b6478d3e47d4ccd. Report an issue: GitHub.

Appendix: source

Thrown at crypto/src/main/java/org/springframework/security/crypto/codec/Hex.java:58

			// Char for top 4 bits
			result[j++] = HEX[(0xF0 & aByte) >>> 4];
			// Bottom 4
			result[j++] = HEX[(0x0F & aByte)];
		}
		return result;
	}

	public static byte[] decode(CharSequence s) {
		int nChars = s.length();
		if (nChars % 2 != 0) {
			throw new IllegalArgumentException("Hex-encoded string must have an even number of characters");
		}
		byte[] result = new byte[nChars / 2];
		for (int i = 0; i < nChars; i += 2) {
			int msb = Character.digit(s.charAt(i), 16);
			int lsb = Character.digit(s.charAt(i + 1), 16);
			if (msb < 0 || lsb < 0) {
				throw new IllegalArgumentException(
						"Detected a Non-hex character at " + (i + 1) + " or " + (i + 2) + " position");
			}
			result[i / 2] = (byte) ((msb << 4) | lsb);
		}
		return result;
	}

}

View on GitHub (pinned to 96852e8860)