JIRA User Directory migration fails due to MembershipNotFoundException
Platform notice: Server and Data Center only. This article only applies to Atlassian products on the Server and Data Center platforms.
Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Except Fisheye and Crucible
Problem
When attempting to migrate users between directories, the following appears in the atlassian-jira.log
and the migration fails:
2015-08-05 16:26:48,790 http-bio-1279-exec-16 ERROR admin 986x303x1 k4vp4h 172.22.48.31 /plugins/servlet/embedded-crowd/directories/migrate/ [embedded.admin.directory.MigrateDirectoryUsersController] User migration failed
java.lang.RuntimeException: com.atlassian.crowd.exception.MembershipNotFoundException: The child entity <captain.planet> is not a member of the parent <power-puff-girls>
at com.atlassian.crowd.embedded.admin.directory.MigrateDirectoryUsersController$1.doInTransaction(MigrateDirectoryUsersController.java:146)
at com.atlassian.sal.core.transaction.HostContextTransactionTemplate$1.doInTransaction(HostContextTransactionTemplate.java:25)
at com.atlassian.jira.DefaultHostContextAccessor.doInTransaction(DefaultHostContextAccessor.java:34)
at sun.reflect.GeneratedMethodAccessor234.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.atlassian.plugin.osgi.hostcomponents.impl.DefaultComponentRegistrar$ContextClassLoaderSettingInvocationHandler.invoke(DefaultComponentRegistrar.java:134)
at com.sun.proxy.$Proxy493.doInTransaction(Unknown Source)
at sun.reflect.GeneratedMethodAccessor234.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
...
Caused by: com.atlassian.crowd.exception.MembershipNotFoundException: The child entity <captain.planet> is not a member of the parent <power-puff-girls>
at com.atlassian.jira.crowd.embedded.ofbiz.OfBizInternalMembershipDao.removeMembership(OfBizInternalMembershipDao.java:204)
at com.atlassian.jira.crowd.embedded.ofbiz.OfBizInternalMembershipDao.removeUserFromGroup(OfBizInternalMembershipDao.java:187)
at com.atlassian.jira.crowd.embedded.ofbiz.OfBizDelegatingMembershipDao.removeUserFromGroup(OfBizDelegatingMembershipDao.java:126)
at com.atlassian.crowd.directory.AbstractInternalDirectory.removeUserFromGroup(AbstractInternalDirectory.java:949)
at com.atlassian.crowd.directory.DelegatedAuthenticationDirectory.removeUserFromGroup(DelegatedAuthenticationDirectory.java:858)
at com.atlassian.crowd.manager.directory.DirectoryManagerGeneric.removeUserFromGroup(DirectoryManagerGeneric.java:785)
Cause
Somehow JIRA has gotten into a state where the database user membership records are referencing the incorrect user group records. It is not known how JIRA got into this state.
Workaround
This workaround requires delicate database changes, if you're uncertain about making the changes please contact Atlassian Support, and provide an XML backup as per Sending JIRA Data to Support.
Always back up your data before performing any modifications to the database. If possible, test any alter, insert, update, or delete SQL commands on a staging server first.
Identify the problematic records - this can be done with the below SQL:
select m.directory_id, m.id, m.parent_id, m.child_id, m.parent_name from cwd_membership m left outer join cwd_group g on m.directory_id = g.directory_id and m.parent_id = g.id where g.group_name is null;
This will return results similar to the below - take note of the
parent_name
(which is the group name):JSP-241279=# select m.id, m.directory_id, m.parent_id, m.child_id, m.parent_name from cwd_membership m left outer join cwd_group g on m.directory_id = g.directory_id and m.parent_id = g.id where g.group_name is null; id | directory_id | parent_id | child_id | parent_name -------+--------------+-----------+----------+--------------------- 10341 | 10100 | 10002 | 10316 | jira-users 10331 | 10100 | 10002 | 10315 | jira-users 18743 | 10100 | 10010 | 10211 | jira-testers 18740 | 10100 | 10010 | 10314 | jira-testers 18742 | 10100 | 10010 | 10313 | jira-testers 18741 | 10100 | 10010 | 10315 | jira-testers 18744 | 10100 | 10010 | 10210 | jira-testers 10023 | 10100 | 10000 | 10111 | jira-administrators 10027 | 10100 | 10001 | 10113 | jira-developers 10024 | 10100 | 10002 | 10112 | jira-users 10020 | 10100 | 10002 | 10110 | jira-users 10021 | 10100 | 10001 | 10110 | jira-developers 10026 | 10100 | 10010 | 10111 | jira-testers 10120 | 10100 | 10002 | 10111 | jira-users 10330 | 10100 | 10002 | 10314 | jira-users 10025 | 10100 | 10002 | 10113 | jira-users 10028 | 10100 | 10001 | 10112 | jira-developers 10220 | 10100 | 10002 | 10210 | jira-users 10221 | 10100 | 10002 | 10211 | jira-users 10340 | 10100 | 10010 | 10316 | jira-testers 10334 | 10100 | 10000 | 10110 | jira-administrators 10323 | 10100 | 10002 | 10313 | jira-users
Run this SQL to find the correct
id
for the groups from the output above. Please ensure to replace theparent_name
as appropriate:select id, group_name from cwd_group where directory_id = 10100 and group_name in ('jira-users','jira-testers','jira-administrators','jira-developers');
This will return the
id
of the groups, which maps to theparent_id
in thecwd_membership
table, for example:id | group_name -------+--------------------- 11314 | jira-users 11313 | jira-testers 11312 | jira-administrators 11311 | jira-developers (4 rows)
- Stop JIRA. Ensure it has been backed up!
Update the records from point 2 above with the ids from point 4. In this example, we're doing the following which will update the
parent_id
to be the correctid
from step 4:update cwd_membership set parent_id = 11314 where parent_id = 10002 and directory_id = 10100; update cwd_membership set parent_id = 11313 where parent_id = 10010 and directory_id = 10100; update cwd_membership set parent_id = 11312 where parent_id = 10000 and directory_id = 10100; update cwd_membership set parent_id = 11311 where parent_id = 10001 and directory_id = 10100;
- Start JIRA and attempt the migration job again.