spring-projects/spring-security · error · IllegalArgumentException
Invalid algorithm type: X
Error message
Invalid algorithm type: X
What it means
After splitting the encoded hash, decode() dispatches on the algorithm segment (parts[1]); only argon2d, argon2i, and argon2id are supported. Any other identifier — or an empty/garbled one — causes this IllegalArgumentException. The hash's algorithm token must match the PHC Argon2 spec.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/argon2/Argon2EncodingUtils.java:114
* output. Both are required. The binary salt length and the output length must be in
* the allowed ranges defined in argon2.h.
* @param encodedHash the Argon2 hash string as described above
* @return an {@link Argon2Hash} object containing the raw hash and the
* {@link Argon2Parameters}.
* @throws IllegalArgumentException if the encoded hash is malformed
*/
static Argon2Hash decode(String encodedHash) throws IllegalArgumentException {
Argon2Parameters.Builder paramsBuilder;
String[] parts = encodedHash.split("\\$");
if (parts.length < 4) {
throw new IllegalArgumentException("Invalid encoded Argon2-hash");
}
int currentPart = 1;
paramsBuilder = switch (parts[currentPart++]) {
case "argon2d" -> new Argon2Parameters.Builder(Argon2Parameters.ARGON2_d);
case "argon2i" -> new Argon2Parameters.Builder(Argon2Parameters.ARGON2_i);
case "argon2id" -> new Argon2Parameters.Builder(Argon2Parameters.ARGON2_id);
default -> throw new IllegalArgumentException("Invalid algorithm type: " + parts[1]);
};
if (parts[currentPart].startsWith("v=")) {
paramsBuilder.withVersion(Integer.parseInt(parts[currentPart].substring(2)));
currentPart++;
}
String[] performanceParams = parts[currentPart++].split(",");
if (performanceParams.length != 3) {
throw new IllegalArgumentException("Amount of performance parameters invalid");
}
if (!performanceParams[0].startsWith("m=")) {
throw new IllegalArgumentException("Invalid memory parameter");
}
paramsBuilder.withMemoryAsKB(Integer.parseInt(performanceParams[0].substring(2)));
if (!performanceParams[1].startsWith("t=")) {
throw new IllegalArgumentException("Invalid iterations parameter");
}
paramsBuilder.withIterations(Integer.parseInt(performanceParams[1].substring(2)));
if (!performanceParams[2].startsWith("p=")) {View on GitHub (pinned to 96852e8860)
Solutions
- Ensure the hash was produced by an Argon2 variant and its algorithm token is lowercase 'argon2id'/'argon2i'/'argon2d'
- Use the correct decoder/encoder for the actual algorithm (e.g. BCryptPasswordEncoder for '$2a$' hashes)
- During migrations, version-prefix stored hashes and dispatch to the right PasswordEncoder via DelegatingPasswordEncoder
Example fix
// before
PasswordEncoder encoder = new Argon2PasswordEncoder(); // used on legacy bcrypt hashes
// after
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); // routes by {id} prefix Defensive patterns
Strategy: validation
Validate before calling
static boolean isArgon2Algorithm(String encodedHash) {
return encodedHash != null && encodedHash.startsWith("$argon2id$") || encodedHash.startsWith("$argon2i$") || encodedHash.startsWith("$argon2d$");
} Try / catch
try {
return Argon2EncodingUtils.decode(hash);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Invalid algorithm type")) {
throw new UnsupportedHashAlgorithmException(hash, e);
}
throw e;
} Prevention
- Use DelegatingPasswordEncoder so each hash is decoded by its matching encoder
- Keep algorithm tokens lowercase as per the PHC string format
- Detect legacy hash types at login time and re-encode with Argon2 on success
When it happens
Trigger: Calling decode() on a hash whose second '$'-delimited segment is not exactly "argon2d", "argon2i", or "argon2id" — e.g. a bcrypt '$2a$...' string, an scrypt or PBKDF2 hash, or a hash with a case mismatch like 'Argon2id'.
Common situations: Feeding non-Argon2 hashes to Argon2PasswordEncoder.matches() during a password-migration; hand-edited hash strings; case-sensitivity mistakes when normalizing hashes.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid encoded Argon2-hash
- Amount of performance parameters invalid
- Invalid memory parameter
- Invalid iterations parameter
- Invalid parallelity parameter
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/bb92487d198bbf51.
Report an issue: GitHub.