chinabugotech/hutool · error · IllegalArgumentException

alphabet must contain at least %d unique characters: %d

Error message

alphabet must contain at least %d unique characters: %d

What it means

Thrown during Hashids construction in validateAndFilterAlphabet() when the custom alphabet array has fewer than MIN_ALPHABET_LENGTH (16) characters. The Hashids algorithm requires a minimum alphabet size of 16 to function correctly. This is a hard requirement enforced at object creation time, not at encode/decode time.

Source

Thrown at hutool-core/src/main/java/cn/hutool/core/codec/Hashids.java:449

		if (salt.length > 0 && spaceLeft > 0) {
			int length = Math.min(salt.length, spaceLeft);
			System.arraycopy(salt, 0, newSalt, offset, length);
			spaceLeft -= length;
			offset += length;
		}
		// 3. alphabet
		if (spaceLeft > 0) {
			System.arraycopy(alphabet, 0, newSalt, offset, spaceLeft);
		}

		// shuffle
		return shuffle(alphabet, newSalt);
	}

	private char[] validateAndFilterAlphabet(final char[] alphabet, final char[] separators) {
		// validate size
		if (alphabet.length < MIN_ALPHABET_LENGTH) {
			throw new IllegalArgumentException(String.format("alphabet must contain at least %d unique " +
					"characters: %d", MIN_ALPHABET_LENGTH, alphabet.length));
		}

		final Set<Character> seen = new LinkedHashSet<>(alphabet.length);
		final Set<Character> invalid = IntStream.range(0, separators.length)
				.mapToObj(idx -> separators[idx])
				.collect(Collectors.toSet());

		// add to seen set (without duplicates)
		IntStream.range(0, alphabet.length)
				.forEach(i -> {
					if (alphabet[i] == ' ') {
						throw new IllegalArgumentException(String.format("alphabet must not contain spaces: " +
								"index %d", i));
					}
					final Character c = alphabet[i];
					if (!invalid.contains(c)) {
						seen.add(c);

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Ensure the custom alphabet array contains at least 16 unique characters.
  2. Use the default DEFAULT_ALPHABET (62 characters) if you do not have a specific requirement for a custom alphabet.
  3. Add a unit test or startup assertion that checks the alphabet length before constructing the Hashids instance.

Example fix

// before
char[] alphabet = "0123456789abcdef".toCharArray(); // 16 chars — OK
Hashids h = new Hashids(salt, alphabet, -1);

char[] tooShort = "0123456789".toCharArray(); // 10 chars — throws
Hashids h2 = new Hashids(salt, tooShort, -1);

// after — always verify length
char[] alphabet = "0123456789abcdef".toCharArray();
if (alphabet.length < 16) throw new IllegalStateException("alphabet too short");
Hashids h = new Hashids(salt, alphabet, -1);
Defensive patterns

Strategy: validation

Validate before calling

if (alphabet.length < 16) {
    throw new IllegalStateException("Alphabet must have at least 16 characters, got: " + alphabet.length);
}

Prevention

When it happens

Trigger: Calling new Hashids(salt, customAlphabet, minLength) or Hashids.create(salt, customAlphabet, minLength) where customAlphabet has fewer than 16 characters (before deduplication and separator filtering). Note the check uses the raw array length, not the post-deduplication unique count.

Common situations: Defining a custom alphabet that is too short for a specialized use case. Accidentally truncating the alphabet array in configuration. Copy-paste errors when defining the alphabet constant.

Related errors


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/c555c646d11ba319. Report an issue: GitHub.