UMS Keycloak Bootstrap Fails During Upgrade to openDesk 1.5.0
Problem:
When upgrading openDesk from version 1.4.x to 1.5.0 (Nubus 1.9.x), the UMS Keycloak bootstrap process fails unexpectedly. While the issue does not appear in pre-production environments, it has been observed in multiple production instances. Specifically, the failure affects the Two-Factor Authentication (2FA) configuration, rendering the setup incomplete and requiring manual recovery steps.
Affected:
- Product/Module: openDesk / UMS Keycloak Bootstrap
- Version Affected: openDesk 1.5.0 (Nubus 1.9.x)
- Applies To: Upgrades from openDesk 1.4.x
Symptoms:
During the execution of the bootstrap process, the enabling for 2FA halts with a fatal error. A 409 Conflict
response is returned by Keycloak, stating:
Authentication execution configuration 2fa-role-mapping already exists
As a result, the bootstrap job does not complete successfully, preventing full Keycloak configuration and requiring manual intervention to proceed.
Logs:
TASK [Enable Two-Factor-Authentication] ****************************************
fatal: [localhost]: FAILED! => {“changed”: false, “cmd”: “univention-keycloak --keycloak-url http://ums-keycloak:8080 --realm opendesk --binduser kcadmin --bindpwdfile /credentials/keycloak.secret 2fa enable --group-2fa="2fa-users" --ldap-base="dc=swp-ldap,dc=internal"\n”, “delta”: “0:00:02.067930”, “end”: “2025-07-08 05:05:24.087799”, “msg”: “non-zero return code”, “rc”: 1, “start”: “2025-07-08 05:05:22.019869”, “stderr”: “Traceback (most recent call last):\n File "/usr/sbin/univention-keycloak", line 3436, in \n sys.exit(main())\n ^^^^^^\n File "/usr/sbin/univention-keycloak", line 3432, in main\n return opt.func(opt) or 0\n ^^^^^^^^^^^^^\n File "/usr/sbin/univention-keycloak", line 2715, in enable_2fa\n create_conditional_2fa_flow(kc_admin, opt.realm, realm_2fa_role, flow_name)\n File "/usr/sbin/univention-keycloak", line 2979, in create_conditional_2fa_flow\n create_config_for_execution(kc_admin, config, condition_user_role_id)\n File "/usr/sbin/univention-keycloak", line 3009, in create_config_for_execution\n return raise_error_from_response(data_raw, KeycloakGetError, expected_codes=[204, 201])\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File "/usr/lib/python3/dist-packages/keycloak/exceptions.py", line 192, in raise_error_from_response\n raise error(\nkeycloak.exceptions.KeycloakGetError: 409: b’{"errorMessage":"Authentication execution configuration 2fa-role-mapping already exists"}'”, “stderr_lines”: [“Traceback (most recent call last):”, " File "/usr/sbin/univention-keycloak", line 3436, in “, " sys.exit(main())”, " ^^^^^^“, " File "/usr/sbin/univention-keycloak", line 3432, in main”, " return opt.func(opt) or 0", " ^^^^^^^^^^^^^“, " File "/usr/sbin/univention-keycloak", line 2715, in enable_2fa”, " create_conditional_2fa_flow(kc_admin, opt.realm, realm_2fa_role, flow_name)“, " File "/usr/sbin/univention-keycloak", line 2979, in create_conditional_2fa_flow”, " create_config_for_execution(kc_admin, config, condition_user_role_id)“, " File "/usr/sbin/univention-keycloak", line 3009, in create_config_for_execution”, " return raise_error_from_response(data_raw, KeycloakGetError, expected_codes=[204, 201])“, " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^”, " File "/usr/lib/python3/dist-packages/keycloak/exceptions.py", line 192, in raise_error_from_response", " raise error(", “keycloak.exceptions.KeycloakGetError: 409: b’{"errorMessage":"Authentication execution configuration 2fa-role-mapping already exists"}'”], “stdout”: “Enabling 2FA …\nUsing KC_URL: http://ums-keycloak:8080\nGroup already exists\nGroup already exists”, “stdout_lines”: [“Enabling 2FA …”, “Using KC_URL: http://ums-keycloak:8080”, “Group already exists”, “Group already exists”]}
Root Cause:
This issue is caused by the non-idempotent behavior of the univention-keycloak
CLI tool, which attempts to recreate an authentication execution configuration that already exists.
Technical Insight:
- Keycloak requires each authentication execution configuration alias (such as
2fa-role-mapping
) to be unique. - Upon re-running the bootstrap, the job tries to create an execution configuration that already exists from a prior run or incomplete cleanup.
- The duplicate entries in the Keycloak database cause a
409 Conflict
, breaking the bootstrap process.
Workaround:
To recover from this issue and allow the bootstrap job to succeed:
Manual Cleanup in Keycloak UI:
-
Log into the Keycloak Admin Console for the affected realm (typically
opendesk
). -
Navigate to Authentication → Flows.
-
Delete the conditional flow associated with
2fa-role-mapping
.
-
Go to Authentication → Executions and remove any remaining 2FA-related executions.
-
Re-run the bootstrap job:
helm upgrade --install ... --set keycloak-bootstrap.enabled=true
Alternative Cleanup via Database (Advanced):
Caution: Direct database modifications should only be performed by experienced administrators and with appropriate backups.
-
Connect to the PostgreSQL database used by Keycloak.
-
Inspect the
authenticator_config
table:SELECT * FROM authenticator_config WHERE alias = '2fa-role-mapping';
-
Identify all redundant entries:
SELECT * FROM authenticator_config_entry WHERE authenticator_id IN (...);
-
Delete all stale entries:
DELETE FROM authenticator_config_entry WHERE authenticator_id IN (...);
DELETE FROM authenticator_config WHERE alias = '2fa-role-mapping';
-
Rerun the bootstrap process.
helm upgrade --install ... --set keycloak-bootstrap.enabled=true
Database Investigation
To identify which entries are also available and outdated and which are in use:
-
Cross-reference the
id
fromauthenticator_config
with foreign key relationships in other tables such as:authentication_execution
authenticator_config_entry
keycloak=# select * from authenticator_config;
id | alias | realm_id
--------------------------------------+---------------------------+--------------------------------------
d0e23b44-9ea4-4af6-b175-912fe7eb4ecf | review profile config | 4dc5b609-b312-4c45-97f6-c6d5ad1db
802ea9c7-7e9e-4270-9d33-b146990ad | create unique user config | 4dc5b609-b312-4c45-97f6-c6d5ad1db1
d55cd22e-1dd3-4e7a-90f6-18c7409cdf | review profile config | opendesk
e9616ba9-3873-46ea-835f-29f1f3286a | create unique user config | opendesk
0f978e63-154a-42ba-89e5-11e851b4f | 2fa-role-mapping | opendesk
f1e0d786-9d97-477e-b4e3-2816bff790 | 2fa-role-mapping | opendesk
aab1534e-9167-4451-9061-c22d1295b | 2fa-role-mapping | opendesk
77092ec7-bc98-4a66-a4bc-8d694d87d | 2fa-role-mapping | opendesk
13cea73e-65f4-406c-b28f-a3cb9844d | 2fa-role-mapping | opendesk
34fa8cef-46e1-4b41-8653-ae1263981 | 2fa-role-mapping | opendesk
(10 rows)
keycloak=# select * from authenticator_config_entry ;
authenticator_id | value | name
--------------------------------------+----------+--------------------------------------------
802ea9c7-7e9e-4270-9d33-b146990adc | false | require.password.update.after.registration
d0e23b44-9ea4-4af6-b175-912fe7eb4e | missing | update.profile.on.first.login
d55cd22e-1dd3-4e7a-90f6-18c7409cdf | missing | update.profile.on.first.login
e9616ba9-3873-46ea-835f-29f1f3286a | false | require.password.update.after.registration
0f978e63-154a-42ba-89e5-11e851b4f9 | 2FA role | condUserRole
f1e0d786-9d97-477e-b4e3-2816bff790 | 2FA role | condUserRole
aab1534e-9167-4451-9061-c22d1295 | 2FA role | condUserRole
77092ec7-bc98-4a66-a4bc-8d694d87 | 2FA role | condUserRole
13cea73e-65f4-406c-b28f-a3cb9844d | 2FA role | condUserRole
34fa8cef-46e1-4b41-8653-ae1263981 | 2FA role | condUserRole
(10 rows)
Our recommendation to resolve this issue is as follows:
- Remove all entries from both authenticator_config and authenticator_config_entry tables.
- Rerun the keycloak-bootstrap job. This process should recreate the necessary and correct entries.