JCMA "We couldn't export Custom Field Config Scheme": three causes, three fixes
Mihai Perdum
Author
11 min readSeptember 30, 2026
Key takeaways
The same JCMA error has three documented causes: an orphaned project role in a user picker's User Filtering (the knowledge base), a context with a null name (MIG-2113), and Epic Status with no options on fresh Jira 8.15 or 8.16 installs (MIG-589).
Read the log line before you fix anything. The context name and the text after Reason tell the three causes apart.
The knowledge base's PostgreSQL query casts the role id to char, which is one character in Postgres, and its UPDATE matches a different id column from the one the instructions tell you to use.
Cloud exposes a single user picker's user filtering over REST as userFilter with enabled, groups and roleIds, so you can check what arrived after the migration.
Atlassian documents no Cloud-to-Cloud equivalent of this error, and says nothing about how Copy product data handles field contexts or user filtering.
JCMA stops with "We couldn't export Custom Field Config Scheme" and a java.lang.NullPointerException, and the same message has three unrelated causes. That is the trap. You search the error, you find Atlassian's knowledge base article for it, you run its SQL, it finds nothing wrong or it points you at a user picker you have never heard of, and the project still will not export.
The knowledge base article, JCMA export error: "We couldn't export Custom Field Config Scheme", was last updated on 26 September 2025 and documents one cause only. The second cause lives in a bug ticket, MIG-2113. The third lives in another, MIG-589. Both tickets are titled some version of "JCMA export throws java.lang.NullPointerException", and both are closed as fixed, but the data that triggers them can still sit in your database.
This piece is for the person holding a Data Center to Cloud migration that just failed on this line. There is a section at the end for Cloud to Cloud, which does not go through JCMA at all.
Why JCMA export throws java.lang.NullPointerException here
A custom field config scheme is what the Jira UI calls a custom field context: the combination of projects and issue types a field applies to, plus its options and default value. In the database it is the fieldconfigscheme table, and its name is the configname column. JCMA exports each context the projects in the migration use. If one of them has data the exporter does not expect, it throws a NullPointerException and that project's export stops.
The knowledge base puts it this way for its cause: JCMA "will identify that the information is corrupted and not proceed with the export of the affected projects." The affected projects, not the whole plan. That matches what people see: some projects go through, one does not.
Three causes of the JCMA export error on a custom field
Here are the three log lines, verbatim from Atlassian's own pages. Compare yours against them before you touch the database.
text
1Cause 1, knowledge base:
2<date> <time> ERROR <pkey> project-export We couldn't export Custom Field Config Scheme '<context-name>'. Reason: java.lang.NullPointerException: Parameter specified as non-null is null: method com.atlassian.jira.migration.export.framework.ExportService.exportOrThrow
34Cause 2, MIG-2113:
5project-export We couldn't export Custom Field Config Scheme 'null'. Reason: java.lang.NullPointerException: getName(...) must not be null. [JCMA 000]
67Cause 3, MIG-589:
8ERROR TP project-export We couldn't export Custom Field Config Scheme 'Default Configuration Scheme for Epic Status'. Reason: java.lang.NullPointerException.
The name in quotes and the text after Reason: are the tell. A real context name plus Parameter specified as non-null is null is cause 1. The literal word 'null' as the name plus getName(...) must not be null is cause 2. 'Default Configuration Scheme for Epic Status' is cause 3.
Orphaned project role in User Filtering
User picker fields can restrict who you can pick, by group or by project role. That setting is called User Filtering and it is stored per context, in userpickerfilter and userpickerfilterrole. The knowledge base says: "The following error message will appear when there is an orphaned or deleted project role ID linked to a User Filtering configuration associated with a custom field context." Delete a project role that a filter still points at and you have it.
The knowledge base gives a diagnostic query for PostgreSQL, MySQL, Oracle and SQL Server. This is the PostgreSQL one, verbatim:
sql
1SELECT cf.id AS customfieldid
2, cf.cfname AS customfieldname
3, fcs.id AS customfieldcontextid
4, fcs.configname AS customfieldcontextname
5, upf.id AS userpickerfilterid
6, upfr.projectroleid AS userpickerfilterprojectroleid
7,COALESCE(CAST(pr.id ASchar),'Project role ID not found')AS projectroleid
8,COALESCE(pr.name,'Project role name not found')AS projectrolename
9FROM userpickerfilter upf
10JOIN fieldconfigscheme fcs ON fcs.id = upf.customfieldconfig
11JOIN customfield cf ON cf.id = upf.customfield
12LEFTJOIN userpickerfilterrole upfr ON upfr.userpickerfilter = upf.id
13LEFTJOIN projectrole pr ON pr.id = upfr.projectroleid;
A row reading "Project role ID not found" is your orphan. The fix it gives is to pick a real role from the projectrole table and run:
sql
1UPDATE userpickerfilterrole SET projectroleid =<project-role-ID>where id =<affected-picker-filter-ID>;
followed by "create a new migration to migrate the project again". A new migration, not a retry.
Null configname in fieldconfigscheme
MIG-2113 is the second cause. Its steps to reproduce are two lines: "Have a null config name in the fieldconfigscheme table" and "Attempt a project by project migration via JCMA to Cloud". It lists Affects Version "JCMA - 1.12.8", it is Closed as Fixed, and the last comment, from 3 March 2026, says "Released on JCMA 1.12.53". The ticket's expected behaviour was to "Prompt users to update config schemes". It does not say what 1.12.53 actually does with a null name now, so if you are on an older JCMA, or you want to be sure, fix the data.
The workaround, verbatim, starts with "Before making any database updates perform a database backup in case a restore is required", then:
sql
1UPDATE fieldconfigscheme SET configname ='<Configuration Scheme Name>'WHERE id =<config scheme ID>;
Atlassian gives no query to find the row. This one is mine, not theirs:
sql
1SELECT id, fieldid, configname FROM fieldconfigscheme WHERE configname ISNULL;
Epic Status with no options on Jira 8.15 and 8.16
MIG-589 is the oldest of the three, created in May 2021 and closed as fixed that October. Its description: "For Jira versions 8.15 and 8.16 when running a migration with JCMA, the migration fails". The reason given is that "On those versions of Jira, no options for the Epic Status is created - therefore we don't have a default value for that field". The stack trace stops in CustomFieldConfigSchemeExporter.getDefaultValue, which fits.
Two conditions narrow it a lot. It "doesn't appear if you previously had an instance with 8.14 or earlier and upgraded to 8.15", so it is fresh 8.15 and 8.16 installs. And migrations "are successful when using Jira versions 8.14 or 8.17-EAP02". The only version statement on the fix is a comment: "Should have been in JCMA 1.5.8".
There is no SQL here. Epic Status is a locked Jira Software field, and "As the field is created in Jira Software there's no way to set it". The workaround is done in the UI, backup first: unlock the field, open Epic Status, remove the duplicated default configuration scheme so the project uses the global context, set the default value to "To Do", lock the field again, retry. One user on the ticket found two Epic Status fields in their list, one marked deprecated, and deleting the deprecated one fixed it. Another noted the field "is not even configured for the project we are trying to migrate, but still it's breaking the migration". So do not rule this cause out just because Epic Status is not configured for your project; one user on the ticket hit it that way.
Three problems in the knowledge base's own SQL
I ran the knowledge base's PostgreSQL query and fix on a throwaway PostgreSQL 16.15 database with a stub of these tables: only the columns the queries name, seeded with one good role, one deleted role, a filter pointing at both, a context with a null name, and an Epic Status context with no options. We have no Data Center instance, so this is not a real Jira schema, and the column names are taken from Atlassian's own query. Three things came out of it.
First, CAST(pr.id AS char). In PostgreSQL char with no length is one character. The query still flags the orphan correctly, because that is driven by COALESCE, but the role id it does find is cut short:
text
1 userpickerfilterprojectroleid | projectroleid | projectrolename
2 10100 | 1 | Developers
3 10101 | Project role ID not found | Project role name not found
Role 10100 shows as 1. Use CAST(pr.id AS varchar) if you want to read it.
Second, the fix points at the wrong id. The knowledge base says to take the id "from the userpickerfilterid column" of the query. That column is userpickerfilter.id. The UPDATE's WHERE id = is on userpickerfilterrole, a different table, and the query never returns that table's id. On my stub, running the UPDATE with the userpickerfilterid value, inside a transaction I rolled back, did this:
text
1UPDATE 0
It changed nothing because no role row had that id. On a real database the two id sequences can overlap, and then the same statement rewrites some other filter's role instead. The query to run first is this one, mine, which returns the id the UPDATE actually needs:
sql
1SELECT upf.id AS userpickerfilterid, upfr.id AS userpickerfilterrole_id, upfr.projectroleid,2COALESCE(CAST(pr.id ASvarchar),'Project role ID not found')3FROM userpickerfilter upf
4LEFTJOIN userpickerfilterrole upfr ON upfr.userpickerfilter = upf.id
5LEFTJOIN projectrole pr ON pr.id = upfr.projectroleid;
text
1 userpickerfilterid | userpickerfilterrole_id | projectroleid | projectroleid
2 1 | 11 | 10100 | 10100
3 1 | 12 | 10101 | Project role ID not found
With WHERE id = 12 the UPDATE hit exactly one row, the orphan, and left row 11 alone.
Third, a small one: the instruction tells you to replace an <affected-project-role-ID> placeholder that does not appear in the UPDATE, which has <project-role-ID> and <affected-picker-filter-ID>. And unlike both tickets, the knowledge base's fix carries no backup warning. Take the backup anyway.
For the other two causes the stub did what the tickets describe: my null-name query found the context, MIG-2113's UPDATE named it, and a count of Epic Status options per context returned zero for the seeded one. That last query joins options to contexts through a column I modelled myself, so treat it as a sketch until you have checked it against your own schema.
We couldn't import Custom Field Config Scheme: the Cloud side
1ERROR PTL project-import We couldn't import Custom Field Config Scheme 'n'. Reason: NullPointerException: No message. This caused 1 other items to fail.
2ERROR PTL project-import We couldn't import Custom Field Default Value 'NDT configuration scheme'. Reason: IllegalArgumentException: Expect one config for custom field config scheme 18405.
3ERROR PTL project-import We couldn't import Project PTL. Reason: IllegalArgumentException: Workflow scheme [14690] does not exist. This caused 4722 other items to fail.
The poster said of 'NDT configuration scheme' that "there is no scheme with that name", and the only reply, from Jack Brickey, asks whether it was ever solved. That is still a Data Center to Cloud run, failing on the Cloud side of it, not a Cloud-to-Cloud error.
After a migration that does go through, you can check what landed. On our own Cloud test site today, GET /rest/api/3/field/{fieldId}/context lists a field's contexts, and for a single user picker GET /rest/api/3/field/{fieldId}/context/defaultValue returns the user filtering too:
That userFilter object is the Cloud counterpart of the two tables above. A multi user picker on the same site returned only type and contextId, no userFilter key, and nothing I read explains why. I have not run a JCMA migration for this piece, so I cannot tell you whether a Data Center role id arrives in roleIds. Epic Status on the same site has one context, named "Default Configuration Scheme for Epic Status", the same name as in MIG-589, with three options: To Do, In Progress and Done.
This is the same check-on-the-destination habit as in the issue security level version of this error, which is the same class of failure: a JCMA NullPointerException over a reference to something that was deleted.
Custom field contexts in Cloud to Cloud migration
Cloud to Cloud has no JCMA, so you will not see this message, and there is no database to run SQL against. Atlassian's page What data is copied lists "✅ Field configuration scheme", "✅ Project roles", "Epic status" among the epic fields, and user pickers, single and multiple, among the custom field types it copies. It says nothing about field contexts or user filtering. I have not run a cross-site copy for this piece, so I cannot tell you how either behaves. What you can do is run the same two REST calls against the source and the destination and compare them field by field, using the destination's own field ids.
Before you rerun the server to cloud migration
Match the log line to one of the three causes first. For cause 1 get the userpickerfilterrole id from the corrected query, not the one the knowledge base names. For cause 2 find the null name and give it one. For cause 3 fix Epic Status in the UI. Then back up, fix, re-run the finding query until it returns nothing, and start a new migration for the project.
What this does not cover
The database half was run on a stub PostgreSQL schema, not a live Jira, and the MySQL, Oracle and SQL Server variants were not run. Atlassian publishes no finding query for causes 2 and 3; the ones here are mine. The Cloud half was read live, with no JCMA run behind it, and the Cloud-to-Cloud half rests on the documentation plus the REST check.