Self-Service Password Forgotten returns Portal temporarily unavailable
Problem
On the login screen, below the credential input form, there is a Self-Service link for Forgot your password (non-SSO login, without Keycloak installed).
The link should be reachable via:
https://fqdn/univention/selfservice/#selfservice/passwordforgotten
When accessing this URL, the following error appears:
Sorry.
The portal is temporarily unavailable. If the problem persists, please contact your system administrator.
Environment
- UCS 5.2-4
- System Role: Primary Node
self-serviceandself-service-backendinstalled- Non-SSO login (no Keycloak in use)
Investigation
Interestingly, the module passwordforgotten is reachable via:
https://fqdn/univention/portal/#selfservice/passwordforgotten
This causes confusion, as the functionality itself is working, but not via the intended /selfservice/ path.
Service Status
root@ucs5primary:~# systemctl status univention-portal-server.service
● univention-portal-server.service - Univention Portal server
Loaded: loaded (/lib/systemd/system/univention-portal-server.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-02-10 10:02:07 CET; 1 week 1 day ago
Main PID: 2735 (univention-port)
Tasks: 2 (limit: 38464)
Memory: 134.6M
CPU: 3.648s
CGroup: /system.slice/univention-portal-server.service
└─2735 /usr/bin/python3 /usr/sbin/univention-portal-server
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: File "/usr/lib/python3/dist-packages/univention/portal/extensions/portal.py", line 92, in get_visible_content
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: announcements = self.portal_cache.get_announcements()
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: File "/usr/lib/python3/dist-packages/univention/portal/extensions/cache.py", line 99, in get_announcements
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: return deepcopy(self.get()["announcements"])
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: ~~~~~~~~~~^^^^^^^^^^^^^^^^^
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: KeyError: 'announcements'
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: 500 GET /univention/selfservice/portal.json (127.0.0.1) 5.11ms
Feb 18 17:04:15 ucs5primary univention-portal-server[2735]: 404 GET /univention/selfservice/i18n/en.json (127.0.0.1) 0.29ms
syslog Output
Feb 18 17:27:49 ucs5primary postfix/smtpd[2767331]: connect from ucs5replica.univention.intranet[10.100.0.20]
Feb 18 17:27:49 ucs5primary postfix/smtpd[2767331]: NOQUEUE: reject: RCPT from ucs5replica.univention.intranet[10.100.0.20]: 454 4.7.1 <munin@univention.intranet>: Relay access denied; from=<> to=<munin@univention.intranet> proto>
Feb 18 17:27:49 ucs5primary postfix/smtpd[2767331]: disconnect from ucs5replica.univention.intranet[10.100.0.20] ehlo=2 starttls=1 mail=1 rcpt=0/1 data=0/1 rset=1 quit=1 commands=6/8
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: 2767117 user 26-02-18 17:27:55 [ DEBUG]: no user given
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: 2767117 cache 26-02-18 17:27:55 [ INFO]: loading cache file /var/cache/univention-portal/groups.json
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: 2767117 cache 26-02-18 17:27:55 [ INFO]: loading cache file /var/cache/univention-portal/selfservice.json
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: Uncaught exception GET /univention/selfservice/portal.json (127.0.0.1)
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: HTTPServerRequest(protocol='https', host='portal.univention.intranet', method='GET', uri='/univention/selfservice/portal.json', version='HTTP/1.1', remote>
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: Traceback (most recent call last):
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: File "/usr/lib/python3/dist-packages/tornado/web.py", line 1721, in _execute
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: result = await result
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: ^^^^^^^^^^^^
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: File "/usr/lib/python3/dist-packages/univention/portal/handlers/portal_entries_handler.py", line 31, in get
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: visible_content = portal.get_visible_content(user, admin_mode)
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: File "/usr/lib/python3/dist-packages/univention/portal/extensions/portal.py", line 92, in get_visible_content
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: announcements = self.portal_cache.get_announcements()
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: File "/usr/lib/python3/dist-packages/univention/portal/extensions/cache.py", line 99, in get_announcements
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: return deepcopy(self.get()["announcements"])
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: ~~~~~~~~~~^^^^^^^^^^^^^^^^^
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: KeyError: 'announcements'
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: 2767117 server 26-02-18 17:27:55 [ ERROR]: Error during service
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: 500 GET /univention/selfservice/portal.json (127.0.0.1) 55.73ms
Feb 18 17:27:55 ucs5primary univention-portal-server[2767117]: 404 GET /univention/selfservice/i18n/en.json (127.0.0.1) 0.36ms
Analysis
The logs clearly indicate a cache problem:
KeyError: 'announcements'
The portal server attempts to load:
/var/cache/univention-portal/selfservice.json
The JSON files in /var/cache/univention-portal/ define how the portal is rendered.
Normally, the cache can be rebuilt using:
univention-portal update
However, in this case the cache was not updated:
root@ucs5primary:~# univention-portal update
Updating default
Portal data updated in 1.67s
Updating selfservice
Portal data untouched
Updating umc
Portal data untouched
File timestamp:
root@ucs5primary:~/univention-support# ls -lah /var/cache/univention-portal/selfservice.json
-rw------- 1 root nogroup 527K 18. Apr 2023 /var/cache/univention-portal/selfservice.json
Root Cause
The reason why selfservice.json is not updated is that the Self-Service portal object is missing in LDAP.
Verification:
root@ucs5primary:~/univention-support# univention-ldapsearch -b cn=portal,cn=portals,cn=univention,$(ucr get ldap/base) | grep cn=self-service
No output.
root@ucs5primary:~/univention-support# udm portals/portal list --filter cn=self-service | less
cn=self-service
Example of a correct object:
root@ucs5primary:~# udm portals/portal list --filter cn=self-service
cn=self-service
DN: cn=self-service,cn=portal,cn=portals,cn=univention,dc=miro,dc=intranet
background: None
categories: cn=self-service-profile,cn=category,cn=portals,cn=univention,dc=miro,dc=intranet
categories: cn=self-service-password,cn=category,cn=portals,cn=univention,dc=miro,dc=intranet
categories: cn=self-service-new-account,cn=category,cn=portals,cn=univention,dc=miro,dc=intranet
defaultLinkTarget: samewindow
displayName: en_US: Self Service
ensureLogin: FALSE
logo: None
name: self-service
showUmc: FALSE
univentionObjectIdentifier: b41dbe72-2d1d-435e-be1d-a5d7259b5294
Because the portal object does not exist, univention-portal update cannot rebuild /var/cache/univention-portal/selfservice.json.
Solution
1. Create the Self-Service portal object via UDM
udm portals/portal create --position "cn=portal,cn=portals,cn=univention,$(ucr get ldap/base)" \
--set name=self-service \
--set background=None \
--set categories="cn=self-service-profile,cn=category,cn=portals,cn=univention,$(ucr get ldap/base)" \
--set categories="cn=self-service-password,cn=category,cn=portals,cn=univention,$(ucr get ldap/base)" \
--set categories="cn=self-service-new-account,cn=category,cn=portals,cn=univention,$(ucr get ldap/base)" \
--set defaultLinkTarget=samewindow \
--set displayName='"en_US" "Self Service"' \
--set ensureLogin=FALSE \
--set logo=None \
--set showUmc=FALSE
Output:
WARNING: multiple values for categories given via --set. Use --append instead!
Object created: cn=self-service,cn=portal,cn=portals,cn=univention,dc=univention,dc=intranet
Verification:
udm portals/portal list --filter cn=self-service
cn=self-service
DN: cn=self-service,cn=portal,cn=portals,cn=univention,dc=miro,dc=intranet
background: None
categories: cn=self-service-profile,cn=category,cn=portals,cn=univention,dc=miro,dc=intranet
categories: cn=self-service-password,cn=category,cn=portals,cn=univention,dc=miro,dc=intranet
categories: cn=self-service-new-account,cn=category,cn=portals,cn=univention,dc=miro,dc=intranet
defaultLinkTarget: samewindow
displayName: en_US: Self Service
ensureLogin: FALSE
logo: None
name: self-service
showUmc: FALSE
univentionObjectIdentifier: bb3c63c0-1045-464d-bbbd-82df14d0d76b
2. Rebuild /var/cache/univention-portal/selfservice.json
univention-portal update
Output:
Updating default
Portal data updated in 4.25s
Updating selfservice
Portal data updated in 3.09s
Updating umc
Portal data untouched
Verification:
ls -lah /var/cache/univention-portal/selfservice.json
-rw------- 1 root nogroup 503K 19. Feb 11:28 /var/cache/univention-portal/selfservice.json
3. Restart the portal server
systemctl restart univention-portal-server.service
Result
After recreating the missing Self-Service portal object, rebuilding the portal cache, and restarting the portal service, the URL:
https://fqdn/univention/selfservice/#selfservice/passwordforgotten
is accessible again:


