• Products
  • Documentation
  • Resources

Jira Site Import pre-migration checklist

Site Import will no longer be available for Server to Cloud migrations

From February 1, 2022, we’ll discontinue Server to Cloud migrations using Site Import depending on the number of users you’re looking to migrate.

If you’re looking to migrate:

  • 1-10 users - Site Import will be available until Jan 31, 2022

  • 11 - 100 users - Site Import will be available until Feb 28, 2022

  • 101-250 users - Site Import will be available until Mar 31, 2022

  • 251 - 1000 users - Site Import will be available until Apr 30, 2022

  • More than 1000 users - Site Import will continue to be available until further notice.

To view the number of licensed Jira Server or Data Center users, see the Viewing your licensed user count section on the Licensing your Jira applications page.

We recommend you use the Jira Cloud Migration Assistant for all your migration needs. The Migration Assistant offers several benefits including Apps and Jira Service Management migrations. We’ll soon support Advanced Roadmaps migrations.

For more information on this announcement, read our Community post. For any technical or compatibility concerns with this change, contact us.

Before you begin this checklist for Jira Site Import, make sure you’ve chosen the right migration method for your needs. We recommend the Jira Cloud Migration Assistant for most migrations as we’re actively investing in making it the easiest and most reliable way to move from Jira Server to Jira Cloud.

To complete the pre-migration checks below, you may need access to:

1. Check your Jira Server version [mandatory]

For the import to work, your backup XML file needs to be from a supported version of Jira Server or Data Center. 

Verify using the Jira Server UI

  1. Click on the cog icon in the application's right upper corner

  2. Select System

  3. Select System Information in the left navigation panel

  4. Finally, look for the Jira Version

Verify using your Support Zip

Product version verification

1 2 3 4 5 grep "<product name" <Support Zip Location>/application-properties/application.xml Example Output: <product name="Jira" version="8.7.1"/>

Verify using your XML backup file

You can cross-reference the build number to the Jira version using Jira Server Build and Versions.

Product version verification

1 2 3 4 5 grep 'Build #' <Backup File Location>/entities.xml Example Output: Build # : 100118

2. Check your XML file is valid [mandatory]

Ensure that both entities.xml and the activeobjects.xml are valid XML files. Sometimes exports from large customers with complex environments result in invalid XML structures.

Verify using your XML backup file

Use the query below to find out if your file is valid:

1 2 xmllint --noout <Backup File Location>/entities.xml xmllint --noout <Backup File Location>/activeobjects.xml : 100118

If the command does not produce an output, the file is valid. Any exceptions point to the spot with the formatting error.

3. Check your XML file structure [mandatory]

Ensure that the backup file is correctly structured for import. If you have a large instance, we recommend splitting your Cloud backup file into a database file containing your activeobjects.xml and entities.xml, and a separate one for your attachments and other media.

This can help avoid timeout errors and reduce the risk of issues on import.

The total size of the .xml files should be less than or equal to 10GB before zipping and importing the file. To import larger files, contact support.

Verify using your XML backup file

Depending on if you separate data from your media and other attachments or not, make sure the resulting hierarchy matches the relevant format below:

Attachments and data

1 2 3 4 5 6 7 JIRA-backup-XXXXXX ├── activeobjects.xml ├── entities.xml ├── data │ ├── attachments │ └── avatars └── logos

Attachments and other media only

1 2 3 4 5 6 7 8 9 10 media-only-X.zip └─── data ├── attachments │ ├── ProjectKey │ │ └── 10000 │ │ ├── IssueKey-1 │ │ ├── IssueKey-2 │ │ └── IssueKey-3 │ └─── ProjectKey2 └── avatars

4. Check for failed upgrade tasks [mandatory]

Failed or pending upgrade tasks from Jira Server may cause an import to Cloud to fail. 

Verify using your XML backup file

Run the following to identify any failed upgrade tasks before attempting an import into cloud:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 grep '<UpgradeHistory' <Backup File Location>/entities.xml | awk 'BEGIN{ORS="\n"};{print $2}{print $5"\n"}' Example Output: id="10000" status="complete" id="10100" status="complete" id="10101" status="complete" id="10104" status="complete" id="10105" status="failed"

 

1 2 3 4 5 6 7 8 9 10 11 12 grep '<UpgradeTaskHistory' <Backup File Location>/entities.xml | awk 'BEGIN{ORS="\n"};{print $2}{print $5"\n"}' Example Output: id="10000" status="complete" id="10100" status="complete" id="10101" status="complete" id="10104" status="complete" id="10105" status="failed"

If any upgrade tasks return with "failed", the workaround is to update them to "complete" or remove the failed upgrade tasks altogether. Make sure that the resulting XML structure is valid when removing the elements.

Once the change is made, save the file and re-zip, making sure to keep the same file structure as the original backup file.

5. Check for duplicate and invalid user emails [mandatory]

One of the most common reasons for a failed import is duplicate or invalid emails. Although import checks can capture duplicate or invalid emails, it can result in failed imports or uploads that can take time and extend a maintenance window for large customers. It's a best practice to try and capture these beforehand.

Verify using your XML backup file

Duplicate users

Run the following to identify any duplicate emails (denoted by more than 1 to the left of the email):

1 2 3 4 5 6 7 grep 'lowerEmailAddress="' <Backup File Location>/entities.xml | awk -F\lowerEmailAddress=\" '{print $2}' | cut -d\" -f1 | sort | uniq -с Example Output: 1 felix.test@test.com 2 fixed.test@test.com 1 florian.test@test.com

Below is additional query for db (with same function as above).

1 2 3 4 5 SELECT lower_email_address, count(lower_email_address), array_agg(user_name) AS "Users with Dupe E-Mail" FROM cwd_user GROUP BY lower_email_address HAVING count(lower_email_address) > 1;

If you find duplicates, correct them on the source instance or edit the entities.xml to make them unique.

Additionally, add-on users may cause issues on migration. You can prevent these by cleaning up add-on users before importing to Cloud.

Verify using SQL (tested on Postgres)

Add-on users

Use the query below to find any users that meet such criteria and either delete them or update their emails on the source to reflect something other than @connect.atlassian.com:

1 2 --ADD-ON USERS - TESTED ON POSTGRESQL select * from cwd_user where lower_email_address like 'connect.atlassian.com';

6. Turn off the incoming mail handlers in Cloud during testing [mandatory]

By default, the incoming mail handlers are turned on after an import. This can cause mail handlers in Cloud to process emails instead of mail handlers in Server. We strongly recommend turning these off during testing to prevent mails from incorrect processing.

You can do the following:

  1. Click Jira Settings > System.

  2. Select Global Mail Settings, and then turn off Email puller and Email processor.

  3. Select Incoming Mail, and then delete all mail servers and handlers.

  4. If you have Jira Service Management, go to Settings > Products Email requests, and make sure the Email addresses section is empty.

7. Check for invalid or unhandled characters [mandatory]

In older versions of Jira, it was possible to cut and paste text containing control characters into Jira issue fields. This causes problems, because Jira's backup format is XML, and XML does not allow for the storage of most control characters. When XML containing control characters is imported into Jira, the import fails with an irreversible error.

To prevent this, follow our guide to removing invalid characters from an XML backup for both entities.xml file and activeobjects.xml files.

8. Fix any duplicate workflows [mandatory]

An import may fail if there are workflows with the same name in the backup file. By design, workflows may not have the same name creating them through the user interface. However, if the workflow names have the same name but with different casing (e.g. "workflow1" vs "WORKFLOW1"), then it can lead to a failed import.

Verify using your XML backup file

Duplicate workflows

Use the following query to make sure all of your workflow names are unique:

1 2 3 4 5 6 7 8 9 10 11 12 13 cat <Backup File Location>/entities.xml | grep '<Workflow id="' | cut -d " " -f7- | sort | uniq -c Example Output: 1 name="Software Simplified Workflow for Project SER"> 1 name="Software Simplified Workflow for Project SKP"> 1 name="Software Simplified Workflow for Project TES"> 1 name="TEST: Change Management workflow for Jira Service Desk"> 1 name="TEST: Incident Management workflow for Jira Service Desk"> 1 name="TEST: Jira Service Desk default workflow"> 1 name="TEST: Problem Management workflow for Jira Service Desk"> 1 name="TEST: Service Request Fulfilment with Approvals workflow for Jira Service Desk"> 1 name="TEST: Service Request Fulfilment workflow for Jira Service Desk"> 1 name="company-managed default workflow">

Make sure each workflow name from the output is unique (has a 1 to the left of the name). If you find duplicates, correct them on the source instance or edit the entities.xml to make them unique.

9. Fix any duplicate clustered jobs [mandatory]

An import may fail if there are duplicate clustered jobs with the same ID in the backup file. You’ll need to ensure that there are no duplicated clustered jobs' IDs prior to import, as outlined in this report.

Verify using SQL (tested on Postgres)

Find duplicate clustered jobs

Use the query below to find any duplicate clustered jobs

1 2 3 SELECT * FROM clusteredjob WHERE job_id in (SELECT job_id FROM clusteredjob GROUP BY job_id HAVING COUNT(*)>1)

Mitigate on the source instance

  1. Shut down JIRA and back up the database properly

  2. Delete either of the duplicate entries: 

    1 delete from clusteredjob where id =XXXXX;
  3. Restart Jira

Verify using your XML backup file

First, run the following query:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 grep 'ClusteredJob id="' <Backup File Location>/entities.xml | cut -d "=" -f2 | sort | uniq -c Example Output: 1 "10001" jobId 1 "10107" jobId 1 "10201" jobId 1 "10202" jobId 1 "10204" jobId 1 "10205" jobId 1 "10300" jobId 1 "10301" jobId 1 "10302" jobId 1 "10303" jobId 1 "10304" jobId 1 "10307" jobId 1 "10308" jobId 1 "10309" jobId 1 "10311" jobId

Make sure each name from the output is unique (has a 1 to the left of the name). If you find duplicates, correct them on the source instance or edit the entities.xml to make them unique.

10. Check the length of your attachment filenames [mandatory]

An import may fail if there are attachments in the backup with a filename greater than 250 characters.

Verify using SQL (tested on Postgres)

The query below will identify attachments with more than 250 characters:

1 2 3 SELECT id,issueid, char_length(filename) FROM fileattachment WHERE char_length(filename) > 250

Verify using your XML backup file

Make sure that the command below does not identify any filenames greater than 250. It should show 0.

1 2 3 4 5 grep <Backup File Location>/entities.xml | cut -d\ -f9 | awk 'length > 250 {print ;}' | wc -l Example Output: 0

If you find any files greater than 250, identify them in the entities.xml and rename them in the field filename="XXXXX.txt"

11. Check your public access settings [mandatory]

You can configure your Jira Server or Jira Cloud site to be publicly available to the internet. Unless content is meant to be public, we highly recommend reviewing project permissions that you have made publicly available in Jira Server, and remove their anonymous access setup before migrating to Cloud.

Verify using SQL (tested on Postgres)

Projects

This will flag any projects that have the Browse Project permission set to Anyone.

1 2 3 4 5 6 7 8 9 10 11 12 13 // get list of project permission schemes which has share type as "Anyone" (i.e. open) SELECT p.id, p.pname, ps.name FROM project p INNER JOIN nodeassociation na ON p.id = na.source_node_id INNER JOIN schemepermissions sp ON na.sink_node_id = sp.scheme INNER JOIN permissionscheme ps ON na.sink_node_id = ps.id WHERE na.source_node_entity = 'Project' AND na.sink_node_entity = 'PermissionScheme' AND sp.permission_key='BROWSE_PROJECTS' AND sp.perm_type='group' AND sp.perm_parameter is null

Filters

This will get a list of filters which has share type as "share with everyone" (i.e. global)

1 2 3 4 5 // get list of filters which has share type as "share with everyone" (i.e. global) SELECT sr.filtername, sp.sharetype AS current_share_state, sr.username AS owner_name, sr.reqcontent AS JQL FROM searchrequest sr INNER JOIN sharepermissions sp ON sp.entityid = sr.id WHERE sp.sharetype='global' and sp.entitytype ='SearchRequest';

Agile Boards

This will get a list of Agile boards which has share type as "share with everyone" (i.e. global)

1 2 3 4 5 6 // get list of Agile boards which has share type as "share with everyone" (i.e. global) SELECT DISTINCT "rv"."NAME" as "Board Name", sr.filtername, sp.sharetype AS current_share_state, sr.username AS owner_name FROM "AO_60DB71_RAPIDVIEW" as rv INNER JOIN searchrequest sr ON sr.id = rv."SAVED_FILTER_ID" INNER JOIN sharepermissions sp ON sp.entityid = sr.id WHERE sp.sharetype='global' and sp.entitytype ='SearchRequest'

Dashboards

This will get a list of Dashboards which has share type as "share with everyone" (i.e. global)

1 2 3 4 5 6 // get list of Dashboard which has share type as "share with everyone" (i.e. global) SELECT DISTINCT pp.id as Dashboard_Id, pp.pagename AS Dashboard_name, sp.sharetype AS current_share_state, pp.username AS owner_name FROM portalpage pp INNER JOIN sharepermissions sp ON sp.entityid = pp.id WHERE sp.sharetype='global' and sp.entitytype ='PortalPage' ORDER BY pp.id;

12. Ensure you won’t exceed your Cloud user limit [mandatory]

Make sure the sum of users to be migrated from Server, plus any users that already exist in Cloud, doesn’t exceed your subscription user tier. For example, if you have a 51-100 user subscription and try to import 110 active users, the migration will fail. 

To resolve this, do one of the following:

Verify using SQL (tested on Postgres)

Use the queries referenced in our Get list of licensed users in Jira Server guide to get the number of licensed users.

Verify using Support Zip

Use the query below before running a migration to verify the number of users to be migrated with your Cloud plan user limit. If needed, reduce the number of users, upgrade your Cloud plan, or add more users to your subscription.

1 2 3 4 grep "<Users>" <Support Zip Location>/application-properties/application.xml Example Output: <Users>2205</Users>

13. Check the size of your attachments [recommended]

Imports into Jira Cloud that contain a large number of attachments (20+ GB uncompressed) may cause long delays or timeouts. We recommend importing your media (attachments, project avatars, and logos) separately after importing your database backup (entities.xml and activeobjects.xml files).

Verify using SQL (tested on Postgres)

The first query below will identify the overall attachment size from the database. The second query will break it down by project if it needs to be assessed further.

1 2 3 4 5 6 7 8 9 10 11 select round(sum(filesize)/1024/1024,2) as "Total Attachment Size(MB)" from fileattachment join jiraissue on jiraissue.id = fileattachment.issueid; select round(sum(filesize)/1024/1024,2) as "Size(MB) by Project", project.pname as "Project Name" from fileattachment join jiraissue on jiraissue.id = fileattachment.issueid join project on project.id = jiraissue.project group by project.pname order by "Size(MB) by Project" desc;

14. Check for orphan data [recommended]

An import may fail if there is orphan data in the backup that is not handled properly in Cloud. A common scenario is null project keys.

Verify using your XML backup file

Try to identify some of the orphan data. If you notice a blank line in the output, you more than likely have a project key that is null and needs to be corrected by making sure the key value is not empty. Correct it in the entities.xml before importing into Cloud.

XML Validity Verification

1 2 3 4 5 6 7 8 xmlstarlet sel -t -v "/entity-engine-xml/Project/@key" -n <Backup File Location>/entities.xml Example Output: SER SKP TEST

15. Check you won't exceed storage limits [recommended]

Atlassian's Cloud plans have different storage limits. Before migrating, take a few minutes to check how much disk space you're currently using and review our Cloud storage documentation.

16. Back up your data  [recommended]

Before you run a migration or any of the updates recommended on this guide, we recommend that you back up your current Jira Server site so that you have a restore point. Similarly, if your destination Cloud site has existing data, back up your Jira Cloud site as well in case you need to revert back post-migration for any reason. This is a best practice and adds a restore point in case the maintenance needs to be reverted.

17. Run a test migration [recommended]

We strongly recommend you run a test migration before running your production migration. Check out our guidance on testing your migration.

18. Notify support of your migration plan [recommended]

If you’re performing your migration over a weekend or holiday, or will have over 1,000 users in Cloud, we recommend getting in touch with our migration support team at least one to two months in advance. That way, we can ensure we have extra support on hand during your migration.

More information and support

We have a number of channels available to help you with your migration.

Additional Help