NCS version: v3.3.0 (behavior also confirmed present on current sdk-nrf main, include/flash_map_pm.h).
THE ISSUE
include/flash_map_pm.h selects which PM partition the DTS storage_partition label resolves to:
#if (CONFIG_SETTINGS_FCB || CONFIG_SETTINGS_NVS || defined(PM_SETTINGS_STORAGE_ID) || CONFIG_SETTINGS_ZMS || CONFIG_SETTINGS_ZMS_LEGACY)
#define storage_partition settings_storage
#elif CONFIG_FILE_SYSTEM_LITTLEFS
...
#elif CONFIG_ZMS
#define storage_partition zms_storage
#endifThe first branch is taken when PM_SETTINGS_STORAGE_ID is defined - i.e. whenever the PM map merely CONTAINS a settings_storage partition - regardless of whether any settings subsystem is enabled. Because it is an #if/#elif chain, this outranks the CONFIG_ZMS branch: an application with CONFIG_SETTINGS disabled and CONFIG_ZMS=y that mounts ZMS via FIXED_PARTITION_OFFSET(storage_partition) gets PM_SETTINGS_STORAGE_OFFSET, not PM_ZMS_STORAGE_OFFSET, with no warning. A static PM map very commonly carries a settings_storage partition (inherited from samples or other images in the sysbuild), so this triggers easily and silently.
TO REPRODUCE
1. Sysbuild app with a pm_static.yml containing BOTH settings_storage and zms_storage partitions, and a DTS storage_partition node at the zms_storage address.
2. App config: CONFIG_ZMS=y, no CONFIG_SETTINGS*.
3. Mount ZMS with fs.offset = FIXED_PARTITION_OFFSET(storage_partition);
4. Observe pm_config.h contains both PM_SETTINGS_STORAGE_ADDRESS and PM_ZMS_STORAGE_ADDRESS, and the app mounts at the settings_storage address.
EXPECTED
With no settings backend enabled, storage_partition should resolve to the partition matching the enabled storage subsystem (zms_storage for CONFIG_ZMS), or at minimum the build should warn that the label was redirected to a partition belonging to a subsystem that is not enabled. Selecting a partition based purely on its existence in the map is surprising: the same source produces different storage addresses depending on unrelated partitions in the map, and plain (non-PM) builds of the same app resolve the DTS address - so behavior differs between build systems.
IMPACT (HOW WE FOUND IT)
On an nRF54LM20A product this silently placed an application ZMS store into an 8 KiB settings_storage partition instead of its 36 KiB dedicated partition. The store's sector rotation then ran past the end of settings_storage and corrupted the adjacent partition (which held device identity keys). The failure looked intermittent for days because sysbuild images and plain builds of the same application read/write different addresses.
SUGGESTED FIX
Condition the first branch on an actual settings backend being enabled, e.g.:
#if (CONFIG_SETTINGS_FCB || CONFIG_SETTINGS_NVS || CONFIG_SETTINGS_ZMS || CONFIG_SETTINGS_ZMS_LEGACY || (defined(PM_SETTINGS_STORAGE_ID) && defined(CONFIG_SETTINGS)))
or emit a build-time diagnostic when storage_partition is redirected to a partition whose subsystem is not enabled.
WORKAROUND (for anyone else hitting this)
Reference the PM partition explicitly in application code:
#ifdef CONFIG_PARTITION_MANAGER_ENABLED
#define STORE_PARTITION zms_storage
#else#define STORE_PARTITION storage_partition
#endifBUILD_ASSERT(FIXED_PARTITION_OFFSET(STORE_PARTITION) == EXPECTED_ADDR);