spring-projects/spring-security · error · IllegalArgumentException
Invalid algorithm type: N
Error message
Invalid algorithm type: N
What it means
Argon2EncodingUtils.encode serializes an Argon2 hash plus parameters into the PHC modular-crypt string format; the Argon2 variant (type) must be one of ARGON2_d, ARGON2_i, or ARGON2_id. Any other integer type value hits the switch default and throws IllegalArgumentException('Invalid algorithm type: N'), since there is no defined encoding prefix for it.
Solutions
- Set the type from the official constants: new Argon2Parameters.Builder(Argon2Parameters.ARGON2_id) (or ARGON2_d / ARGON2_i)
- Prefer Argon2PasswordEncoder, which builds valid parameters internally, over calling Argon2EncodingUtils directly
- Log/inspect parameters.getType() at construction to catch corrupted values early
- If migrating hashes, map foreign variant labels ('argon2d'/'argon2i'/'argon2id') to the matching Spring constant before re-encoding
Example fix
// before
Argon2Parameters params = new Argon2Parameters.Builder(7).build(); // invalid type
Argon2EncodingUtils.encode(hash, params); // IllegalArgumentException
// after
Argon2Parameters params = new Argon2Parameters
.Builder(Argon2Parameters.ARGON2_id)
.withVersion(Argon2Parameters.ARGON2_VERSION_13)
.build();
String encoded = Argon2EncodingUtils.encode(hash, params); Defensive patterns
Strategy: validation
Validate before calling
int type = parameters.getType();
if (type != Argon2Parameters.ARGON2_d && type != Argon2Parameters.ARGON2_i
&& type != Argon2Parameters.ARGON2_id) {
throw new IllegalArgumentException("Unsupported Argon2 type: " + type);
} Type guard
static boolean isValidArgon2Type(int type) {
return type == Argon2Parameters.ARGON2_d
|| type == Argon2Parameters.ARGON2_i
|| type == Argon2Parameters.ARGON2_id;
} Try / catch
try {
return Argon2EncodingUtils.encode(hash, parameters);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Invalid algorithm type")) {
// rebuild parameters with a valid type constant
} else { throw e; }
} Prevention
- Always pass official Argon2Parameters constants, never arbitrary ints
- Use Argon2PasswordEncoder instead of calling Argon2EncodingUtils directly
- Assert the builder type right after constructing Argon2Parameters in tests
- Map foreign-library variant labels to Spring constants during hash migration
When it happens
Trigger: Building Argon2Parameters with a type constant outside {ARGON2_d, ARGON2_i, ARGON2_id} (e.g., a hand-written integer or corrupted value) and then calling encode; decoding a hash string with an unknown variant earlier and re-encoding its parameters; passing parameters constructed by older/foreign code with different constants.
Common situations: Hand-rolling Argon2Parameters instead of using Argon2PasswordEncoder's defaults; interop with libraries whose type constants differ; corrupted stored parameter blobs being re-encoded.
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
- Amount of performance parameters invalid
- Invalid algorithm type: X
- Invalid encoded Argon2-hash
- Invalid iterations parameter
- Invalid memory parameter
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/6883ffb2542d5b2e.
Report an issue: GitHub.
Appendix: source
Thrown at crypto/src/main/java/org/springframework/security/crypto/argon2/Argon2EncodingUtils.java:65
*
* where {@code <T>} is either 'd', 'id', or 'i', {@code <num>} is a decimal integer
* (positive, fits in an 'unsigned long'), and {@code <bin>} is Base64-encoded data
* (no '=' padding characters, no newline or whitespace).
*
* The last two binary chunks (encoded in Base64) are, in that order, the salt and the
* output. If no salt has been used, the salt will be omitted.
* @param hash the raw Argon2 hash in binary format
* @param parameters the Argon2 parameters that were used to create the hash
* @return the encoded Argon2-hash-string as described above
* @throws IllegalArgumentException if the Argon2Parameters are invalid
*/
static String encode(byte[] hash, Argon2Parameters parameters) throws IllegalArgumentException {
StringBuilder stringBuilder = new StringBuilder();
String type = switch (parameters.getType()) {
case Argon2Parameters.ARGON2_d -> "$argon2d";
case Argon2Parameters.ARGON2_i -> "$argon2i";
case Argon2Parameters.ARGON2_id -> "$argon2id";
default -> throw new IllegalArgumentException("Invalid algorithm type: " + parameters.getType());
};
stringBuilder.append(type);
stringBuilder.append("$v=")
.append(parameters.getVersion())
.append("$m=")
.append(parameters.getMemory())
.append(",t=")
.append(parameters.getIterations())
.append(",p=")
.append(parameters.getLanes());
if (parameters.getSalt() != null) {
stringBuilder.append("$").append(b64encoder.encodeToString(parameters.getSalt()));
}
stringBuilder.append("$").append(b64encoder.encodeToString(hash));
return stringBuilder.toString();
}
/**View on GitHub (pinned to 96852e8860)