spring-projects/spring-security · error · IllegalArgumentException
suffix cannot be empty
Error message
suffix cannot be empty
What it means
The DelegatingPasswordEncoder constructor validates that the idSuffix (the delimiter closing the encoder id inside an encoded password, e.g. '}') is non-null and non-empty. An empty suffix would make it impossible to delimit the encoder id from the password hash, so the library refuses construction with this IllegalArgumentException.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/password/DelegatingPasswordEncoder.java:186
* Creates a new instance.
* @param idForEncode the id used to lookup which {@link PasswordEncoder} should be
* used for {@link #encode(CharSequence)}
* @param idToPasswordEncoder a Map of id to {@link PasswordEncoder} used to determine
* which {@link PasswordEncoder} should be used for
* @param idPrefix the prefix that denotes the start of the id in the encoded results
* @param idSuffix the suffix that denotes the end of an id in the encoded results
* {@link #matches(CharSequence, String)}
*/
public DelegatingPasswordEncoder(String idForEncode, Map<String, PasswordEncoder> idToPasswordEncoder,
String idPrefix, String idSuffix) {
if (idForEncode == null) {
throw new IllegalArgumentException("idForEncode cannot be null");
}
if (idPrefix == null) {
throw new IllegalArgumentException("prefix cannot be null");
}
if (idSuffix == null || idSuffix.isEmpty()) {
throw new IllegalArgumentException("suffix cannot be empty");
}
if (idPrefix.contains(idSuffix)) {
throw new IllegalArgumentException("idPrefix " + idPrefix + " cannot contain idSuffix " + idSuffix);
}
if (!idToPasswordEncoder.containsKey(idForEncode)) {
throw new IllegalArgumentException(
"idForEncode " + idForEncode + "is not found in idToPasswordEncoder " + idToPasswordEncoder);
}
for (String id : idToPasswordEncoder.keySet()) {
if (id == null) {
continue;
}
if (!idPrefix.isEmpty() && id.contains(idPrefix)) {
throw new IllegalArgumentException("id " + id + " cannot contain " + idPrefix);
}
if (id.contains(idSuffix)) {
throw new IllegalArgumentException("id " + id + " cannot contain " + idSuffix);View on GitHub (pinned to 96852e8860)
Solutions
- Pass the conventional suffix "}" as the idSuffix argument (matching the {id}encoded format)
- Ensure the variable bound to idSuffix is not null or empty before constructing; add a check in your config code
- Use PasswordEncoderFactories.createDelegatingPasswordEncoder() instead of constructing DelegatingPasswordEncoder manually
Example fix
// before
PasswordEncoder encoder = new DelegatingPasswordEncoder("bcrypt", encoders, "{", "");
// after
PasswordEncoder encoder = new DelegatingPasswordEncoder("bcrypt", encoders, "{", "}"); Defensive patterns
Strategy: validation
Validate before calling
if (idSuffix == null || idSuffix.isEmpty()) {
throw new IllegalArgumentException("idSuffix must be non-empty, e.g. \"}\"");
}
new DelegatingPasswordEncoder(idForEncode, encoders, idPrefix, idSuffix); Try / catch
try {
return new DelegatingPasswordEncoder(idForEncode, encoders, "{", "}");
} catch (IllegalArgumentException e) {
log.error("DelegatingPasswordEncoder construction failed: {}", e.getMessage());
throw e;
} Prevention
- Always pass "}" as the suffix for the standard {id}password format
- Prefer PasswordEncoderFactories.createDelegatingPasswordEncoder() over manual construction
- Validate constructor arguments in your @Bean method before returning the encoder
When it happens
Trigger: Calling the DelegatingPasswordEncoder constructor (typically via PasswordEncoderFactories or directly with new DelegatingPasswordEncoder(idForEncode, idToPasswordEncoder, idPrefix, idSuffix)) passing null or "" (empty string) as the idSuffix argument.
Common situations: Custom password-encoder wiring in Spring Security configuration where the '{id}encoded' prefix format is being customized; copying the constructor call and accidentally dropping or emptying the suffix parameter; programmatic bean definition instead of PasswordEncoderFactories.createDelegatingPasswordEncoder().
Related errors
- idPrefix {idPrefix} cannot contain idSuffix {idSuffix}
- idForEncode {idForEncode}is not found in idToPasswordEncoder
- id {id} cannot contain {idPrefix}
- id {id} cannot contain {idSuffix}
- Unsupported implementation of Sid
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/a0e6c65cff0a4e52.
Report an issue: GitHub.