Jira Data Center fails to start after upgrade due to InvalidPropertyTypeException
Platform Notice: Data Center Only - This article only applies to Atlassian products on the Data Center platform.
Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. 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
Summary
Jira Data Center fails to start after upgrading to 9.15 (including 10.3 LTS) due to an InvalidPropertyTypeException
. The root cause is existing database corruption exposed by a new implementation of the application property set.
Environment
Jira Data Center 9.15.0 and later. All databases are affected. Supplemental logging was added in Jira 10.3.4 / 10.4.2 to aid diagnosis.
Diagnosis
Startup
Jira fails to get past the database connection stage to the plugin framework start during startup. In the atlassian-jira.log
file:
Jira Data Center 9.15.0 - 10.3.3/10.4.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2025-02-15 18:00:00,000+0000 JIRA-Bootstrap ERROR [c.a.j.component.pico.ComponentManager] Error occurred while initializing component 'com.atlassian.jira.plugin.JiraPluginPersistentStateStore'.
com.atlassian.cache.CacheException: com.opensymphony.module.propertyset.InvalidPropertyTypeException
at com.atlassian.cache.memory.DelegatingCache.get(DelegatingCache.java:214)
at com.atlassian.cache.memory.DelegatingCache.get(DelegatingCache.java:165)
at com.atlassian.cache.impl.metrics.InstrumentedCache.get(InstrumentedCache.java:72)
at com.atlassian.jira.cache.stats.CacheWithStats.get(CacheWithStats.java:46)
at com.atlassian.jira.config.properties.v2.DefaultCachingApplicationPropertiesManager.getAllKeysInternal(DefaultCachingApplicationPropertiesManager.java:155)
at com.atlassian.jira.config.properties.v2.DefaultCachingApplicationPropertiesManager.getAllKeys(DefaultCachingApplicationPropertiesManager.java:124)
at com.atlassian.jira.config.properties.v2.ApplicationPropertiesBackedPropertySet.getKeys(ApplicationPropertiesBackedPropertySet.java:74)
at com.atlassian.jira.config.properties.ApplicationPropertiesStore.getStringsWithPrefixFromDb(ApplicationPropertiesStore.java:308)
at com.atlassian.jira.config.properties.ApplicationPropertiesImpl.getStringsWithPrefix(ApplicationPropertiesImpl.java:199)
at com.atlassian.jira.plugin.JiraPluginPersistentStateStore.afterInstantiation(JiraPluginPersistentStateStore.java:95)
at com.atlassian.jira.component.pico.ComponentManager.runInitializingComponents(ComponentManager.java:229)
at com.atlassian.jira.component.pico.ComponentManager.createFullContainer(ComponentManager.java:218)
at com.atlassian.jira.startup.ComponentContainerLauncher.populateFullPicoContainer(ComponentContainerLauncher.java:50)
at com.atlassian.jira.startup.ComponentContainerLauncher.start(ComponentContainerLauncher.java:30)
at com.atlassian.jira.startup.DefaultJiraLauncher.lambda$postDbLaunch$2(DefaultJiraLauncher.java:147)
at com.atlassian.jira.config.database.DatabaseConfigurationManagerImpl.doNowOrEnqueue(DatabaseConfigurationManagerImpl.java:305)
at com.atlassian.jira.config.database.DatabaseConfigurationManagerImpl.doNowOrWhenDatabaseActivated(DatabaseConfigurationManagerImpl.java:202)
at com.atlassian.jira.startup.DefaultJiraLauncher.postDbLaunch(DefaultJiraLauncher.java:144)
at com.atlassian.jira.startup.DefaultJiraLauncher.lambda$start$0(DefaultJiraLauncher.java:109)
at com.atlassian.jira.util.devspeed.JiraDevSpeedTimer.run(JiraDevSpeedTimer.java:31)
at com.atlassian.jira.startup.DefaultJiraLauncher.start(DefaultJiraLauncher.java:107)
at com.atlassian.jira.startup.LauncherContextListener.initSlowStuff(LauncherContextListener.java:162)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: com.opensymphony.module.propertyset.InvalidPropertyTypeException
at com.opensymphony.module.propertyset.ofbiz.StringPropertyHandler.processGet(StringPropertyHandler.java:25)
at com.atlassian.jira.config.properties.v2.OfBizPropertySetApplicationPropertiesDao.lambda$mapToDto$11(OfBizPropertySetApplicationPropertiesDao.java:333)
at java.base/java.util.Optional.map(Unknown Source)
at com.atlassian.jira.config.properties.v2.OfBizPropertySetApplicationPropertiesDao.mapToDto(OfBizPropertySetApplicationPropertiesDao.java:333)
at com.atlassian.jira.config.properties.v2.OfBizPropertySetApplicationPropertiesDao.lambda$findAll$7(OfBizPropertySetApplicationPropertiesDao.java:177)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
at com.atlassian.jira.config.properties.v2.DefaultCachingApplicationPropertiesManager.loadApplicationProperties(DefaultCachingApplicationPropertiesManager.java:176)
at com.atlassian.cache.memory.MemoryCacheManager$2.load(MemoryCacheManager.java:205)
at com.atlassian.cache.memory.DelegatingCache.lambda$get$0(DelegatingCache.java:165)
at com.atlassian.cache.memory.DelegatingCache.lambda$get$1(DelegatingCache.java:193)
at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4903)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3574)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2316)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2189)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2079)
at com.google.common.cache.LocalCache.get(LocalCache.java:4017)
at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4898)
at com.atlassian.cache.memory.DelegatingCache.get(DelegatingCache.java:180)
... 22 more
2025-02-15 18:00:00,000+0000 JIRA-Bootstrap ERROR [c.a.jira.health.HealthChecks] We couldn't start JIRA
2025-02-15 18:00:00,000+0000 JIRA-Bootstrap ERROR [c.a.jira.health.HealthChecks] An error occurred while trying to start JIRA. We can't give you any more detail right now, we suggest checking the logs for more detail and contacting our support team.
Database
The following database queries confirm the problem. All five queries should return nothing. If one or more return rows, you are affected.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
-- Validate boolean, integer, and long types
SELECT *
FROM propertyentry pe
INNER JOIN propertynumber pn ON pn.id = pe.id
WHERE pe.propertytype NOT IN (1, 2, 3)
OR pn.propertyvalue IS NULL;
-- Validate double/decimal type
SELECT *
FROM propertyentry pe
INNER JOIN propertydecimal pd ON pd.id = pe.id
WHERE pe.propertytype <> 4
OR pd.propertyvalue IS NULL;
-- Validate string type
SELECT *
FROM propertyentry pe
INNER JOIN propertystring ps ON ps.id = pe.id
WHERE pe.propertytype <> 5
OR ps.propertyvalue IS NULL;
-- Validate text type
SELECT *
FROM propertyentry pe
INNER JOIN propertytext pt ON pt.id = pe.id
WHERE pe.propertytype <> 6
OR pt.propertyvalue IS NULL;
-- Validate date type
SELECT *
FROM propertyentry pe
INNER JOIN propertydate pd ON pd.id = pe.id
WHERE pe.propertytype <> 7
OR pd.propertyvalue IS NULL;
Cause
Application Property Set
In Jira Data Center 9.15, we revamped the application property set functionality. This resolved JRASERVER-72909 and significantly improved the performance of the "jira.properties
" property set. These properties provide the parameters at ⚙️ (gear icon) > System > General configuration and are critical to the product's startup. The associated tables also store other global data, such as user profile preferences.
Application properties are backed by an OpenSymphony PropertySet, which can store several data types:
Type ordinal | Name | Data table | Mapper | Java type |
---|---|---|---|---|
1 | Boolean (true/false) |
| Number mapper |
|
2 | Integer |
| Number mapper |
|
3 | Long |
| Number mapper |
|
4 | Double (decimal) |
| Decimal mapper |
|
5 | String (255 character max) |
| String mapper |
|
6 | Text (unlimited length) |
| String mapper |
|
7 | Date |
| Date mapper |
|
When a property is retrieved, the propertyentry
table is JOIN
ed on ID
with the corresponding data table, based on the type ordinal. For example, to obtain Jira's Base URL, we check propertystring
(5):
1
2
3
4
5
6
SELECT *
FROM propertyentry pe
JOIN propertystring ps ON pe.id = ps.id
WHERE pe.entity_name = 'jira.properties'
AND pe.entity_id = 1
AND pe.property_key = 'jira.baseurl';
pe.id | entity_name | entity_id | property_key | propertytype | ps.id | propertyvalue |
---|---|---|---|---|---|---|
10207 | jira.properties | 1 | jira.baseurl | 5 | 10207 |
Corrupted Data
If a InvalidPropertyTypeException
is thrown, the property value doesn't match its type. For example, when a text property (6) is stored in propertynumber
, but it should be stored in propertytext
. The 9.15 revamp enforces tighter constraints and will throw exceptions if it encounters this corrupted data. The data was just as corrupted before upgrading, but the new implementation exposes the problem.
Atlassian Support isn't exactly sure how this happens. We haven't been able to reproduce this internally, and typically see this problem with older environments. OpenSymphony PropertySets have been in the product since JIRA 1.0 (2002).
Solution
Always back up your data before making any database modifications. If possible, test any alter, insert, update, or delete SQL commands on a staging server first.
The following queries were written and tested against PostgreSQL. They may need to be adapted to work with another DBMS.
Stop Jira
All Jira nodes must first be completely stopped before executing the following changes.
Delete corrupted data
Execute the following DELETE
statements. This removes entries stored in the wrong data table and cleans up any orphaned values in the data tables.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
-- Clean up boolean, integer, and long types
DELETE
FROM propertyentry
WHERE id IN (SELECT pe.id
FROM propertyentry pe
INNER JOIN propertynumber pn ON pn.id = pe.id
WHERE pe.propertytype NOT IN (1, 2, 3)
OR pn.propertyvalue IS NULL);
-- Remove those orphaned values
DELETE
FROM propertynumber
WHERE id NOT IN (SELECT pe.id FROM propertyentry pe);
-- Clean up double/decimal type
DELETE
FROM propertyentry
WHERE id IN (SELECT pe.id
FROM propertyentry pe
INNER JOIN propertydecimal pd ON pd.id = pe.id
WHERE pe.propertytype <> 4
OR pd.propertyvalue IS NULL);
-- Remove those orphaned values
DELETE
FROM propertydecimal
WHERE id NOT IN (SELECT pe.id FROM propertyentry pe);
-- Clean up string type
DELETE
FROM propertyentry
WHERE id IN (SELECT pe.id
FROM propertyentry pe
INNER JOIN propertystring ps ON ps.id = pe.id
WHERE pe.propertytype <> 5
OR ps.propertyvalue IS NULL);
-- Remove those orphaned values
DELETE
FROM propertystring
WHERE id NOT IN (SELECT pe.id FROM propertyentry pe);
-- Clean up text type
DELETE
FROM propertyentry
WHERE id IN (SELECT pe.id
FROM propertyentry pe
INNER JOIN propertytext pt ON pt.id = pe.id
WHERE pe.propertytype <> 6
OR pt.propertyvalue IS NULL);
-- Remove those orphaned values
DELETE
FROM propertytext
WHERE id NOT IN (SELECT pe.id FROM propertyentry pe);
-- Clean up date type
DELETE
FROM propertyentry
WHERE id IN (SELECT pe.id
FROM propertyentry pe
INNER JOIN propertydate pd ON pd.id = pe.id
WHERE pe.propertytype <> 7
OR pd.propertyvalue IS NULL);
-- Remove those orphaned values
DELETE
FROM propertydate
WHERE id NOT IN (SELECT pe.id FROM propertyentry pe);
Start Jira
Start Jira on a single node and confirm it successfully completes startup.
Was this helpful?