spring-projects/spring-security · error · IllegalArgumentException
idForEncode cannot be null
Error message
idForEncode cannot be null
What it means
DelegatingPasswordEncoder's full constructor requires a non-null idForEncode — the id of the PasswordEncoder used for new encodes — and throws IllegalArgumentException('idForEncode cannot be null') when it is null. The id is used to look up the default encoder in the idToPasswordEncoder map and to tag encoded passwords ({id}...), so it is a mandatory constructor argument.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/password/DelegatingPasswordEncoder.java:180
*/
public DelegatingPasswordEncoder(String idForEncode, Map<String, PasswordEncoder> idToPasswordEncoder) {
this(idForEncode, idToPasswordEncoder, DEFAULT_ID_PREFIX, DEFAULT_ID_SUFFIX);
}
/**
* 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;View on GitHub (pinned to 96852e8860)
Solutions
- Pass a valid id such as "bcrypt" that exists as a key in the idToPasswordEncoder map.
- Load the id from configuration with a non-null default (e.g. properties.getProperty("encoder.id", "bcrypt")).
- Prefer PasswordEncoderFactories.createDelegatingPasswordEncoder() when defaults suffice.
Example fix
// before
String id = properties.get("password.encoder.id"); // null
PasswordEncoder encoder = new DelegatingPasswordEncoder(id, encoders, "{", "}");
// after
String id = properties.getOrDefault("password.encoder.id", "bcrypt");
PasswordEncoder encoder = new DelegatingPasswordEncoder(id, encoders, "{", "}"); Defensive patterns
Strategy: validation
Validate before calling
if (idForEncode == null || !idToPasswordEncoder.containsKey(idForEncode)) {
throw new IllegalArgumentException("idForEncode must be non-null and present in idToPasswordEncoder");
}
PasswordEncoder encoder = new DelegatingPasswordEncoder(idForEncode, idToPasswordEncoder, "{", "}"); Type guard
boolean isValidEncodeId(String id, java.util.Map<String, PasswordEncoder> map) {
return id != null && map != null && map.containsKey(id);
} Try / catch
try {
encoder = new DelegatingPasswordEncoder(idForEncode, idToPasswordEncoder, "{", "}");
} catch (IllegalArgumentException ex) {
encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); // bcrypt default
} Prevention
- Never pass config values straight through; default missing ids to "bcrypt"
- Ensure idForEncode is also a key of idToPasswordEncoder (a separate constructor check will otherwise fail)
- Prefer PasswordEncoderFactories.createDelegatingPasswordEncoder() over manual construction
- Add a startup assertion that the configured encode id resolves to a registered encoder
When it happens
Trigger: Calling new DelegatingPasswordEncoder(null, idToPasswordEncoder, "{", "}") (or the 4-arg variant) with a null id; an id variable sourced from config/constant that resolved to null.
Common situations: Spring config property for the encode id missing and injecting null; refactoring PasswordEncoderFactories-style setup and dropping the "bcrypt" literal; programmatic bean creation with a null default encoder id.
Related errors
- prefix cannot be null
- String cannot be null
- encode cannot be null
- Cannot pass null or empty values to constructor
- password cannot be more than 72 bytes
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/a5fa41e02b5429a6.
Report an issue: GitHub.