spring-projects/spring-security · error · NotFoundException
Object identity not found: <objectIdentity>
Error message
Object identity not found: <objectIdentity>
What it means
deleteAcl resolves the target object identity's primary key in acl_object_identity before deleting its entries and row. If retrieveObjectIdentityPrimaryKey returns null — no ACL row exists for that ObjectIdentity — the service throws NotFoundException because there is nothing to delete.
Source
Thrown at acl/src/main/java/org/springframework/security/acls/jdbc/JdbcMutableAclService.java:300
deleteAcl(child, true);
}
}
}
else {
if (!this.foreignKeysInDatabase) {
// We need to perform a manual verification for what a FK would normally
// do. We generally don't do this, in the interests of deadlock management
List<ObjectIdentity> children = findChildren(objectIdentity);
if (children != null) {
throw new ChildrenExistException(
"Cannot delete '" + objectIdentity + "' (has " + children.size() + " children)");
}
}
}
Long oidPrimaryKey = retrieveObjectIdentityPrimaryKey(objectIdentity);
if (oidPrimaryKey == null) {
throw new NotFoundException("Object identity not found: " + objectIdentity);
}
// Delete this ACL's ACEs in the acl_entry table
deleteEntries(oidPrimaryKey);
// Delete this ACL's acl_object_identity row
deleteObjectIdentity(oidPrimaryKey);
// Clear the cache
this.aclCache.evictFromCache(objectIdentity);
}
/**
* Deletes all ACEs defined in the acl_entry table belonging to the presented
* ObjectIdentity primary key.
* @param oidPrimaryKey the rows in acl_entry to delete
*/
protected void deleteEntries(Long oidPrimaryKey) {View on GitHub (pinned to 96852e8860)
Solutions
- Check existence first (retrieveObjectIdentityPrimaryKey or readAclById) and skip deleteAcl when absent.
- Catch org.springframework.security.acls.model.NotFoundException and treat delete as a no-op (idempotent delete).
- Verify the ObjectIdentity type/identifier matches acl_class/acl_object_identity exactly.
- Confirm the delete is running against the correct datasource/schema.
Example fix
// before
mutableAclService.deleteAcl(oid, true);
// after
try {
mutableAclService.deleteAcl(oid, true);
} catch (NotFoundException ex) {
// ACL already gone; idempotent delete
} Defensive patterns
Strategy: try-catch
Validate before calling
if (((JdbcMutableAclService) aclService).retrieveObjectIdentityPrimaryKey(oid) == null) {
return; // nothing to delete
} Type guard
null
Try / catch
try {
mutableAclService.deleteAcl(oid, true);
} catch (NotFoundException e) {
// idempotent: ACL already gone
} Prevention
- Make delete paths idempotent by swallowing NotFoundException
- Avoid double-invoking delete in retry logic
- Confirm identity type/identifier spelling matches persisted rows
When it happens
Trigger: Calling deleteAcl(objectIdentity, ...) for an ObjectIdentity that was never persisted via createAcl, or deleting twice (double-invocation of a cleanup path), or an identity whose type/identifier spelling differs from the persisted row.
Common situations: Synchronization jobs deleting ACLs for entities already purged; retrying a delete after a partial failure where the ACL row was already removed; deleting ACLs for test data in a fresh database; environment mismatch (ACLs live in another schema).
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}'
- Cannot delete '<objectIdentity>' (has <N> children)
- Object identity not found for ACL: <objectIdentity>
- 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/031b1b37f31e59ee.
Report an issue: GitHub.