alibaba/spring-ai-alibaba · error · IllegalArgumentException

Invalid parallel parameter

Error message

Invalid parallel parameter

What it means

In PasswordCryptUtils.match(), the third performance parameter of the stored Argon2 hash must start with 'p=' to supply the parallelism factor. When perfParams[2] lacks the 'p=' prefix, match() throws this IllegalArgumentException.

Source

Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/utils/security/PasswordCryptUtils.java:118

			int version = Integer.parseInt(parts[0].substring(2));
			builder.withVersion(version);
		}

		String[] perfParams = parts[3].split(",");
		if (perfParams.length != 3) {
			throw new IllegalArgumentException("Amount of performance parameters invalid");
		}

		if (!perfParams[0].startsWith("m=")) {
			throw new IllegalArgumentException("Invalid memory parameter");
		}
		builder.withMemoryAsKB(Integer.parseInt(perfParams[0].substring(2)));
		if (!perfParams[1].startsWith("t=")) {
			throw new IllegalArgumentException("Invalid iterations parameter");
		}
		builder.withIterations(Integer.parseInt(perfParams[1].substring(2)));
		if (!perfParams[2].startsWith("p=")) {
			throw new IllegalArgumentException("Invalid parallel parameter");
		}
		builder.withParallelism(Integer.parseInt(perfParams[2].substring(2)));

		builder.withSalt(b64decoder.decode(parts[4]));

		byte[] decoded = b64decoder.decode(parts[5]);
		byte[] hashBytes = new byte[decoded.length];

		Argon2BytesGenerator generator = new Argon2BytesGenerator();
		generator.init(builder.build());
		generator.generateBytes(password.toCharArray(), hashBytes);

		int result = 0;
		for (int i = 0; i < decoded.length; i++) {
			result |= decoded[i] ^ hashBytes[i];
		}
		return result == 0;
	}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Check parts[3] of the stored hash and fix the third parameter to 'p=<parallelism>'
  2. Regenerate the password hash with PasswordCryptUtils.encode() to guarantee the canonical format
  3. Add a format check (regex on m=,t=,p=) before persisting hashes to catch bad formats at write time

Example fix

// before
m=65536,t=2,par=1
// after
m=65536,t=2,p=1
Defensive patterns

Strategy: validation

Validate before calling

String perfSeg = storedHash.split("\\$")[3];
boolean hasP = perfSeg.split(",")[2].startsWith("p=");
if (!hasP) throw new IllegalStateException("Hash missing p= parallelism param: " + perfSeg);

Type guard

static boolean hasParallelismParam(String hash) {
    String[] parts = hash.split("\\$");
    if (parts.length < 4) return false;
    String[] perf = parts[3].split(",");
    return perf.length == 3 && perf[2].startsWith("p=");
}

Try / catch

try {
    cryptUtils.match(rawPassword, storedHash);
} catch (IllegalArgumentException e) {
    log.warn("Hash parallelism param invalid: {}", e.getMessage());
    throw new AuthenticationException("Credential format invalid");
}

Prevention

When it happens

Trigger: Calling match(rawPassword, storedHash) where the hash's parameter segment's third item is not prefixed with 'p=' (e.g. 'm=65536,t=2,par=1').

Common situations: Hashes serialized by a non-standard Argon2 implementation, hand-edited credentials, or corrupted hash strings after copying between environments.

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 alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/38765ecbed7eaf69. Report an issue: GitHub.