flowable/flowable-engine · error · UsernameNotFoundException
user ( ) could not be found
Error message
user (%s) could not be found
What it means
Flowable's Spring Security integration implements UserDetailsService on top of the Flowable identity (IDM) tables. loadUserByUsername looks up the user via the IdmIdentityService; if no row matches the given userId (after swallowing the FlowableException from the query), it throws Spring Security's UsernameNotFoundException. It signals that authentication cannot proceed because the account does not exist in the Flowable IDM database.
Solutions
- Insert the user into the IDM schema (ACT_ID_USER) via the IdmIdentityService (idmIdentityService.createUser(...).setPassword(...)) or the Flowable Admin/IDM UI, then retry login.
- If users live in LDAP/AD, configure Flowable's LDAP identity integration or a different UserDetailsService instead of relying on the IDM tables.
- Verify the application is connected to the intended database (check flowable/database config) — the user may exist in another environment's DB.
- Catch UsernameNotFoundException in your authentication handling and show a clear 'unknown user' message instead of a generic failure.
Example fix
// before (user missing at login)
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("jsmith", "secret"));
// throws UsernameNotFoundException: user (jsmith) could not be found
// after: provision the user first if missing
if (idmIdentityService.createUserQuery().userId("jsmith").singleResult() == null) {
User u = idmIdentityService.newUser("jsmith");
u.setPassword(passwordEncoder.encode("secret"));
u.setFirstName("John");
u.setLastName("Smith");
idmIdentityService.saveUser(u);
}
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("jsmith", "secret")); Defensive patterns
Strategy: try-catch
Validate before calling
boolean exists = idmIdentityService.createUserQuery().userId(userId).singleResult() != null;
Try / catch
try {
UserDetails user = userDetailsService.loadUserByUsername(userId);
} catch (UsernameNotFoundException e) {
// provision or reject with 'unknown user' response; never reveal stack trace to clients
} Prevention
- Provision users into ACT_ID_USER (or sync from LDAP) as part of environment setup
- Verify DB connection points at the environment you expect before debugging auth failures
- Normalize username case/trimming before lookup
When it happens
Trigger: Calling FlowableUserDetailsService.loadUserByUsername(userId) when the ACT_ID_USER table has no row with that ID; also triggered indirectly by any Spring Security authentication (form login, DaoAuthenticationProvider) configured with this UserDetailsService for a username that is not a Flowable IDM user.
Common situations: Users provisioned in an external directory (LDAP/AD) but the Flowable IDM tables were never synced; typos or case-sensitivity mismatches in usernames; pointing the app at a fresh database without running the identity data scripts; deleting a user while active sessions still reference them.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- Authentication failed for this username and password
- User " + propertyValue + " does not exist
- Authentication failed for this username and password
- Authentication failed for this username and password
- Authentication failed for this username and password
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/746f939a3e29b8cb.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-spring-security/src/main/java/org/flowable/spring/security/FlowableUserDetailsService.java:59
public FlowableUserDetailsService(IdmIdentityService identityService) {
this.identityService = identityService;
}
@Override
public UserDetails loadUserByUsername(String userId)
throws UsernameNotFoundException {
User user = null;
try {
user = this.identityService.createUserQuery()
.userId(userId)
.singleResult();
} catch (FlowableException ex) {
// don't care
}
if (null == user) {
throw new UsernameNotFoundException(
String.format("user (%s) could not be found", userId));
}
return createFlowableUser(user);
}
protected FlowableUser createFlowableUser(User user) {
String userId = user.getId();
List<Privilege> userPrivileges = identityService.createPrivilegeQuery().userId(userId).list();
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Privilege userPrivilege : userPrivileges) {
grantedAuthorities.add(new SimpleGrantedAuthority(userPrivilege.getName()));
}
List<Group> groups = identityService.createGroupQuery().groupMember(userId).list();
if (!groups.isEmpty()) {
List<String> groupIds = new ArrayList<>(groups.size());View on GitHub (pinned to d6d39ce1c6)