Problem
On a UCS 5.2-x node with Dovecot and OX App Suite installed, the system diagnostic check “Check ACL entries of global IMAP folders” (52_mail_acl_sync) may fail with a ValueError.
The Univention System Diagnostic reports the following traceback:
############################### Start 52_mail_acl_sync ###############################
## Check failed: 52_mail_acl_sync - Überprüfe ACL Einträge der globalen IMAP Ordner ##
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/__init__.py", line 250, in execute
ret = execute(umc_module, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py", line 208, in run
differences = list(all_differences(acl_class))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py", line 179, in all_differences
imap_acl = acl_class.from_folder(folder)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py", line 155, in from_folder
acl_list = cls._get_dovecot_acl(folder)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py", line 172, in _get_dovecot_acl
return {identifier.strip(): set(rights.strip().split()) for (identifier, rights) in (line.rsplit(' ', 1) for line in output)}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py", line 172, in <dictcomp>
return {identifier.strip(): set(rights.strip().split()) for (identifier, rights) in (line.rsplit(' ', 1) for line in output)}
^^^^^^^^^^^^^^^^^^^^
ValueError: not enough values to unpack (expected 2, got 1)
################################ End 52_mail_acl_sync ################################
Root Cause
The issue is caused by how the diagnostic plugin /usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py parses the output of doveadm acl get.
The relevant code splits each output line at the last occurrence of two consecutive spaces:
line.rsplit(' ', 1)
For example, the following command:
doveadm acl get -u Administrator shared/foo@domain.de
may return:
ID Global Rights
group=info admin create delete expunge insert lookup post read write write-deleted write-seen -
group=info global admin create delete expunge insert lookup post read write write-deleted write-seen
The last line does not contain two consecutive spaces at the position expected by the parser.
As a result, line.rsplit(' ', 1) returns only one value instead of the two values expected for identifier and rights. The diagnostic check therefore terminates with:
ValueError: not enough values to unpack (expected 2, got 1)
The issue is tracked in Bug 58788:
https://forge.univention.org/bugzilla/show_bug.cgi?id=58788
Workaround
The bug report proposes changing the diagnostic plugin to use the JSON output format provided by doveadm instead of parsing its human-readable text output.
The proposed patch has also successfully resolved the issue in another affected environment.
The patch is available here:
https://forge.univention.org/bugzilla/attachment.cgi?id=11367
1. Create the patch file
Save the following content as 52_mail_fix.patch:
--- 52_mail_acl_sync.py.org52 2025-09-29 16:59:36.000000000 +0200
+++ 52_mail_acl_sync.py 2025-11-09 20:47:28.232054378 +0100
@@ -3,6 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
import itertools as it
+import json
import subprocess
from collections.abc import Iterator
from typing import Any, TypeVar
@@ -167,9 +168,9 @@
def _get_dovecot_acl(folder: Any) -> dict[str, set]:
mailbox = 'shared/{pm}' if folder.mail_address else '{cn}/INBOX'
admin_user = custom_username("Administrator", configRegistry)
- cmd = ('doveadm', 'acl', 'get', '-u', admin_user, mailbox.format(cn=folder.common_name, pm=folder.mail_address))
- output = subprocess.check_output(cmd, stderr=subprocess.PIPE).decode('UTF-8', 'replace').splitlines()
- return {identifier.strip(): set(rights.strip().split()) for (identifier, rights) in (line.rsplit(' ', 1) for line in output)}
+ cmd = ('doveadm', '-f', 'json', 'acl', 'get', '-u', admin_user, mailbox.format(cn=folder.common_name, pm=folder.mail_address))
+ output = json.loads(subprocess.check_output(cmd, stderr=subprocess.PIPE))
+ return {line["id"]: set(line["rights"].strip().split()) for line in output}
def all_differences(acl_class: type[DovecotACL]) -> Iterator[tuple]:
2. Back up the diagnostic plugin
Before applying the patch, create a backup of the original diagnostic plugin:
cp /usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py /usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py.bak
3. Apply the patch
Apply the patch with:
patch /usr/lib/python3/dist-packages/univention/management/console/modules/diagnostic/plugins/52_mail_acl_sync.py 52_mail_fix.patch
The modified diagnostic plugin uses:
doveadm -f json acl get
instead of parsing the regular text output of doveadm acl get. The structured JSON output avoids the dependency on whitespace formatting that causes the original diagnostic check to fail.
After applying the patch, run the 52_mail_acl_sync system diagnostic check again to verify that it completes successfully.
Important
This workaround modifies a file provided by an installed UCS package. A subsequent package update may overwrite the modification.
Keep the backup and the patch file until an official fix for Bug 58788 is installed. After installing an update that contains the official fix, verify whether the workaround is still required.
References
-
Univention Bugzilla – Bug 58788:
https://forge.univention.org/bugzilla/show_bug.cgi?id=58788 -
Proposed patch for Bug 58788:
https://forge.univention.org/bugzilla/attachment.cgi?id=11367
Ich habe den Workaround bewusst als temporären Patch gekennzeichnet, da die Änderung direkt eine paketverwaltete Python-Datei unter /usr/lib/python3/dist-packages/ betrifft.