spring-projects/spring-security · error · UnsupportedOperationException
encode is not supported
Error message
encode is not supported
What it means
UnmappedIdPasswordEncoder is the default matcher used when an encoded password's id has no registered delegate. Matching may be delegated to it, but encoding is meaningless (it would have to pick an arbitrary id), so encodeNonNullPassword unconditionally throws UnsupportedOperationException.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/password/DelegatingPasswordEncoder.java:291
String encodedPassword = extractEncodedPassword(prefixEncodedPassword);
return this.passwordEncoderForEncode.upgradeEncoding(encodedPassword);
}
}
private String extractEncodedPassword(String prefixEncodedPassword) {
int start = prefixEncodedPassword.indexOf(this.idSuffix);
return prefixEncodedPassword.substring(start + this.idSuffix.length());
}
/**
* Default {@link PasswordEncoder} that throws an exception telling that a suitable
* {@link PasswordEncoder} for the id could not be found.
*/
private class UnmappedIdPasswordEncoder extends AbstractValidatingPasswordEncoder {
@Override
protected String encodeNonNullPassword(String rawPassword) {
throw new UnsupportedOperationException("encode is not supported");
}
@Override
protected boolean matchesNonNull(String rawPassword, String prefixEncodedPassword) {
String id = extractId(prefixEncodedPassword);
if (id != null && !id.isBlank()) {
throw new IllegalArgumentException(String.format(NO_PASSWORD_ENCODER_MAPPED, id));
}
if (prefixEncodedPassword != null && !prefixEncodedPassword.isBlank()) {
int start = prefixEncodedPassword.indexOf(DelegatingPasswordEncoder.this.idPrefix);
int end = prefixEncodedPassword.indexOf(DelegatingPasswordEncoder.this.idSuffix, start);
if (start < 0 && end < 0) {
throw new IllegalArgumentException(NO_PASSWORD_ENCODER_PREFIX);
}
}
throw new IllegalArgumentException(String.format(MALFORMED_PASSWORD_ENCODER_PREFIX,
DelegatingPasswordEncoder.this.idPrefix, DelegatingPasswordEncoder.this.idSuffix));
}View on GitHub (pinned to 96852e8860)
Solutions
- Encode via a real delegate encoder (e.g. BCryptPasswordEncoder) or ensure the DelegatingPasswordEncoder was built with a valid idForEncode registered in idToPasswordEncoder
- Catch UnsupportedOperationException and route encoding to an actual encoder
- Do not expose the UnmappedIdPasswordEncoder inner encoder as the encoding path in custom code
Example fix
// before String encoded = unmappedIdEncoder.encode(rawPassword); // throws // after String encoded = delegatingPasswordEncoder.encode(rawPassword); // uses idForEncode delegate
Defensive patterns
Strategy: try-catch
Validate before calling
if (encoder instanceof DelegatingPasswordEncoder d) {
// ensure encoding goes through a real delegate, i.e. the encoder was built with a valid idForEncode
} Type guard
if (encoder instanceof DelegatingPasswordEncoder) {
// safe to encode(); the UnmappedId placeholder is internal and not normally exposed
} Try / catch
try {
encoded = encoder.encode(rawPassword);
} catch (UnsupportedOperationException e) {
encoded = realDelegateEncoder.encode(rawPassword);
} Prevention
- Only call encode() through a properly constructed DelegatingPasswordEncoder with a registered idForEncode
- Do not reach into internal/fallback encoders via reflection
When it happens
Trigger: Calling encode() on a DelegatingPasswordEncoder whose configured idForEncode resolves to the internal UnmappedIdPasswordEncoder — practically, calling encode on a misconstructed or misused delegating encoder rather than a real delegate.
Common situations: Reflection or framework code resolving the encoder by type and invoking encode without knowing it is the unmapped-id placeholder; custom subclassing that routes encoding through the fallback encoder.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- %s does not store credentials
- suffix cannot be empty
- idPrefix {idPrefix} cannot contain idSuffix {idSuffix}
- idForEncode {idForEncode}is not found in idToPasswordEncoder
- id {id} cannot contain {idPrefix}
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/04507421e1302840.
Report an issue: GitHub.