spring-projects/spring-security · error · IllegalArgumentException

Invalid memory parameter

Error message

Invalid memory parameter

What it means

Within the performance-parameter segment, the first component must start with 'm=' followed by the memory cost in KB. If performanceParams[0] lacks the 'm=' prefix, decode() throws this IllegalArgumentException. This enforces the PHC parameter ordering (m=,t=,p=) for Argon2.

Source

Thrown at crypto/src/main/java/org/springframework/security/crypto/argon2/Argon2EncodingUtils.java:125

			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=")) {
			throw new IllegalArgumentException("Invalid parallelity parameter");
		}
		paramsBuilder.withParallelism(Integer.parseInt(performanceParams[2].substring(2)));
		paramsBuilder.withSalt(b64decoder.decode(parts[currentPart++]));
		return new Argon2Hash(b64decoder.decode(parts[currentPart]), paramsBuilder.build());
	}

	public static class Argon2Hash {

		private byte[] hash;

View on GitHub (pinned to 96852e8860)

Solutions

  1. Rewrite the hash's parameter segment into the canonical 'm=<kb>,t=<it>,p=<par>' order and re-verify with a known password
  2. Regenerate hashes with Spring Security's Argon2PasswordEncoder, which always emits canonical order
  3. Validate the format '$argon2(id|i|d)$v=\d+$m=\d+,t=\d+,p=\d+$...' before decoding

Example fix

// before
String hash = "$argon2id$v=19$t=3,m=65536,p=1$..."; // wrong order
// after
String hash = "$argon2id$v=19$m=65536,t=3,p=1$...";
Defensive patterns

Strategy: validation

Validate before calling

static boolean paramsInCanonicalOrder(String encodedHash) {
    String[] parts = encodedHash.split("\\$");
    return parts.length >= 3 && parts[2].matches("m=\\d+,t=\\d+,p=\\d+");
}

Try / catch

try {
    return Argon2EncodingUtils.decode(hash);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("parameter")) {
        throw new MalformedHashFormatException(hash, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling decode() on a hash whose parameter segment's first field does not begin with 'm=' — e.g. fields reordered to 't=3,m=65536,p=1', or a corrupted segment.

Common situations: Hashes produced by tools emitting parameters in non-standard order; manual editing of hash strings; attempts to normalize hashes across libraries that broke the ordering.

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/fdd47457cc2d42e8. Report an issue: GitHub.