spring-projects/spring-security · error · NotFoundException
Object identity not found for ACL: <objectIdentity>
Error message
Object identity not found for ACL: <objectIdentity>
What it means
updateAcl persists ACE changes by deleting and recreating the acl_entry rows for the ACL, which requires the acl_object_identity primary key for the ACL's ObjectIdentity. If no persisted ACL row matches that identity, NotFoundException("Object identity not found for ACL") is thrown — you cannot update an ACL that was never created via createAcl.
Source
Thrown at acl/src/main/java/org/springframework/security/acls/jdbc/JdbcMutableAclService.java:366
catch (DataAccessException notFound) {
return null;
}
}
/**
* This implementation will simply delete all ACEs in the database and recreate them
* on each invocation of this method. A more comprehensive implementation might use
* dirty state checking, or more likely use ORM capabilities for create, update and
* delete operations of {@link MutableAcl}.
*/
@Override
public MutableAcl updateAcl(MutableAcl acl) throws NotFoundException {
Assert.notNull(acl.getId(), "Object Identity doesn't provide an identifier");
// Delete this ACL's ACEs in the acl_entry table
Long oidPrimaryKey = retrieveObjectIdentityPrimaryKey(acl.getObjectIdentity());
if (oidPrimaryKey == null) {
throw new NotFoundException("Object identity not found for ACL: " + acl.getObjectIdentity());
}
deleteEntries(oidPrimaryKey);
// Create this ACL's ACEs in the acl_entry table
createEntries(acl);
// Change the mutable columns in acl_object_identity
updateObjectIdentity(acl);
// Clear the cache, including children
clearCacheIncludingChildren(acl.getObjectIdentity());
// Retrieve the ACL via superclass (ensures cache registration, proper retrieval
// etc)
return (MutableAcl) super.readAclById(acl.getObjectIdentity());
}
private void clearCacheIncludingChildren(ObjectIdentity objectIdentity) {View on GitHub (pinned to 96852e8860)
Solutions
- Call createAcl(objectIdentity) first, then mutate and updateAcl the returned MutableAcl.
- Obtain the MutableAcl from readAclById/readAclsById instead of constructing AclImpl instances manually.
- Catch NotFoundException and fall back to createAcl for identities that may be new.
- Ensure no concurrent deleteAcl races with updateAcl (wrap in a transaction).
Example fix
// before MutableAcl acl = new AclImpl(oid, 1L, aclAuthorizationStrategy, new ConsoleAuditLogger()); acl.insertAce(0, permission, sid, true); mutableAclService.updateAcl(acl); // after MutableAcl acl = (MutableAcl) aclService.readAclById(oid); acl.insertAce(acl.getEntries().size(), permission, sid, true); mutableAclService.updateAcl(acl);
Defensive patterns
Strategy: try-catch
Validate before calling
if (((JdbcMutableAclService) aclService).retrieveObjectIdentityPrimaryKey(acl.getObjectIdentity()) == null) {
mutableAclService.createAcl(acl.getObjectIdentity());
} Type guard
null
Try / catch
try {
mutableAclService.updateAcl(acl);
} catch (NotFoundException e) {
MutableAcl created = mutableAclService.createAcl(acl.getObjectIdentity());
// re-apply changes to created
} Prevention
- Never construct AclImpl instances manually for persistence; read them from the service
- Create the ACL before mutating ACEs for new entities
- Wrap read-modify-write in a transaction to avoid concurrent deletes
When it happens
Trigger: Building a MutableAclImpl in memory (e.g. new AclImpl(oid, ...)) or mutating an ACL obtained elsewhere and calling updateAcl without ever having called createAcl for that object identity; calling updateAcl after the ACL row was deleted concurrently.
Common situations: Constructing ACL objects programmatically in tests or batch jobs instead of reading them from the service; applying ACE changes to a brand-new entity before ACL creation; a concurrent deleteAcl removing the row between read and update.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Unable to find ACL information for object identity '{oid}'
- Object identity not found: <objectIdentity>
- Unable to locate ACL to update
- AclEntryAfterInvocationProvider.noPermission
- Authenticated principal required to operate with ACLs
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/9da87badc4315adc.
Report an issue: GitHub.