Problem: OX-Connector Synchronization Blocked - No such user in Context

Problem

After deleting a user (e.g., uid=max) in Univention Corporate Server (UCS), the ox-connector.log repeatedly shows synchronization errors for this specific user. Consequently, LDAP synchronization to Open-Xchange (OX) has halted completely, preventing any new directory changes from reflecting in the OX web interface.

Error Trace from /var/log/univention/listener_modules/ox-connector.log

2026-06-12 10:38:34 INFO    utils._handle_output:246  Task uid=max,cn=users,dc=company,dc=com (56819d8c-9438-103b-9ea1-cff9eabf22b5; users/user; tasks:1) now has an error count of 906
2026-06-12 10:38:34 INFO    utils._handle_output:246  Error while handling uid=max,cn=users,dc=company,dc=com (56819d8c-9438-103b-9ea1-cff9eabf22b5; users/user; tasks:1)
2026-06-12 10:38:34 INFO    utils._handle_output:246  No such user(s) 3227 in context 10; exceptionId -592283074-2544
2026-06-12 10:38:34 INFO    utils._handle_output:246  Traceback (most recent call last):
2026-06-12 10:38:34 INFO    utils._handle_output:246    File "/tmp/univention-ox-connector.listener_trigger", line 172, in main
2026-06-12 10:38:34 INFO    utils._handle_output:246      run(obj)
2026-06-12 10:38:34 INFO    utils._handle_output:246    File "/usr/lib/python3.9/site-packages/univention/ox/provisioning/__init__.py", line 109, in run
2026-06-12 10:38:34 INFO    utils._handle_output:246      delete_user(obj)
2026-06-12 10:38:34 INFO    utils._handle_output:246    File "/usr/lib/python3.9/site-packages/univention/ox/provisioning/users.py", line 565, in delete_user
2026-06-12 10:38:34 INFO    utils._handle_output:246      user.remove()
2026-06-12 10:38:34 INFO    utils._handle_output:246    File "/usr/lib/python3.9/site-packages/univention/ox/soap/backend.py", line 271, in remove
2026-06-12 10:38:34 INFO    utils._handle_output:246      self.service(self.context_id).delete(obj)
2026-06-12 10:38:34 INFO    utils._handle_output:246    File "/usr/lib/python3.9/site-packages/univention/ox/soap/services.py", line 1077, in delete
2026-06-12 10:38:34 INFO    utils._handle_output:246      return self._call_ox('delete', **kwargs)
...
2026-06-12 10:38:34 INFO    utils._handle_output:246  zeep.exceptions.Fault: No such user(s) 3227 in context 10; exceptionId -592283074-2544
2026-06-12 10:38:34 INFO    utils._handle_output:246  Waiting for 1200 seconds for retry. In case you want to retry now, restart the univention-appcenter-listener-converter@ox-connector service

Environment

  • UCS Version: 5.2-x
  • OX-Connector Version: 3.0.0 or higher

Root Cause

Starting with version 3.0.0, the OX-Connector stores its synchronization task queue inside a SQLite database rather than utilizing temporary JSON files. This architecture keeps track of scheduled tasks along with historical metadata of synchronized items.

By default, the application is configured to stop queue processing immediately upon encountering an error to protect data consistency:

  • OX_CONNECTOR_STOP_ON_ERROR: This environment variable controls error handling behavior. When set to True (default), the connector halts entirely on any failed task and retries indefinitely until the administrator intervenes. Consequently, subsequent synchronization updates are blocked.
  • Idling between runs: In case of consecutive errors, the OX Connector now sleeps longer and longer between runs. This is done to prevent log files filling up with the same error rather quickly. The delay between runs increases with every consecutive error up to 20 minutes.

Investigation

Check the Container Configuration

Verify the current environment properties of the OX-Connector container using the following App Center command:

univention-app configure ox-connector --list
OX_SOAP_SERVER: 'https://ucs5backup.deadpool.intranet' (The server where Open-Xchange is installed)
OX_IMAP_SERVER: 'imap://ucs5backup.deadpool.intranet:143' (Default IMAP server for new users (if not set explicitely there))
OX_SMTP_SERVER: 'smtp://ucs5backup.deadpool.intranet:587' (Default SMTP server for new users (if not set explicitely there))
DEFAULT_CONTEXT: 10 (Default context for users (has to exist))
OX_LANGUAGE: 'de_DE' (Default language for new users)
LOCAL_TIMEZONE: 'Europe/Berlin' (Default timezone for new users)
OX_MASTER_ADMIN: 'oxadminmaster' (OX Admin username (the OX Admin can create, modify, delete contexts; has to exist))
OX_MASTER_PASSWORD: ',qYhiTvHg71jOzB73,3H' (OX Admin password)
Falling back to initial value for OX_IMAP_LOGIN
OX_IMAP_LOGIN: None (imapLogin field that is used by OX to log in to the user's inbox. If this value is empty it is set to the user's mail address.)
Falling back to initial value for OX_FUNCTIONAL_ACCOUNT_LOGIN_TEMPLATE
OX_FUNCTIONAL_ACCOUNT_LOGIN_TEMPLATE: None (Customizes the functional account login field format using templates. You can use plain text or incorporate UDM properties, which have to be enclosed within double curly braces, such as '{{fa_entry_uuid}}{{username}}'." For more details, please refer to the <a target="_blank" href="https://docs.software-univention.de/ox-connector-app/latest/configuration.html#envvar-OX_FUNCTIONAL_ACCOUNT_LOGIN_TEMPLATE">OX-Connector manual</a>.)
Falling back to initial value for OX_USER_IDENTIFIER
OX_USER_IDENTIFIER: None (UDM user property that is used as the unique user identifier for OX. Default: "username".)
Falling back to initial value for OX_GROUP_IDENTIFIER
OX_GROUP_IDENTIFIER: None (UDM group property that is used as the unique group identifier for OX. Default: "name".)
OX_ENABLE_DEPUTY_PERMISSIONS: False (Enables the provisioning of user deputy permissions. Additional steps are needed to activate this feature. Please refer to the instructions in the <a target="_blank")
OX_CONNECTOR_LOG_LEVEL: 'INFO' (Ox-connector log level)
OX_CONNECTOR_STOP_ON_ERROR: True (If the Connector finds an error while processing a particular object (e.g., invalid data that OX rejects), it stops. If this setting is unchecked, the App continues to process other pending tasks; the problematic object is moved to a list of errors for the Administrator to monitor at another time.)

Locate the Blocking Task

OX-Connector provides a built-in command-line tool wrapping the internal SQLite layer: univention-ox-connector-task-management.

The database contains three main tables:

  • tasks: Each row represents one current task of the Connector, it has not yet been successfully processed. Tasks are ordered by their creation time.
  • old: Each row represents an object in the state it was synchronized successfully. Used when processing a task that references this object.
  • morgue: Each row represents a task that failed to be synchronized with a certain error. These failed tasks will not be processed, they need to be individually examined by an administrator.
usage: db.py [-h] action ...

This program lets you manage the database of the OX Connector.
    There are three tables:
    tasks: Each row represents one current task of the Connector, it has not yet been successfully processed. Tasks are ordered by their creation time.
    old: Each row represents an object in the state it was synchronized successfully. Used when processing a task that references this object.
    morgue: Each row represents a task that failed to be synchronized with a certain error. These failed tasks will not be processed, they need to be individually examined by an administrator.
    

optional arguments:
  -h, --help           show this help message and exit

subcommands:
  type db.py <action> --help for further help and possible arguments

  action
    show-item          
                       Shows all rows in our tables that we got for an item. Other commands can
                       give a more verbose output:
                       * Last time it was synced successfully (see search-old)
                       * Pending tasks that shall be processed (see search-tasks)
                       * Current failures that may need interaction (see search-morgue)
                       Output can be either "simple" or "json"
                       
    resync-item        
                       An item is resynced using the latest data that is currently saved in UDM
                       
    summarize-tasks    
                       Shows a brief summary of the tasks table (queue of current tasks).
                       Output can be either "simple" or "json"
                       
    summarize-morgue   
                       Shows a brief summary of the morgue table.
                       Output can be either "simple", "fuller" or "json"
                       
    add-task           
                       Adds the content of a JSON file as a new item to the tasks table.
                       Note: PATH needs to be accessible from inside the OX Connector container,
                       e.g., in /var/lib/univention-appcenter/apps/ox-connector/data/
                       
    search-tasks       
                       Search items from the tasks database (queue of current tasks). Items found
                       can be printed in different formats ("simple" or "fuller" or "json")
                       
    move-task-to-old   
                       Move the task to the old table, meaning that this data is now
                       considered the last snapshot for further updates of this object. Removed
                       from the list of the tasks table.
                       
    move-task-to-morgue
                       
                       Move the task to the morgue table, meaning that it needs further, manual
                       investigation. This can be used to unblock the connector. Removed from the
                       tasks table.
<skip>

To find the blocking task ID, extract it from the log message or run the queue status command:

univention-ox-connector-task-management search-tasks

From the log snippet, the problematic entry is identified via:
Task uid=max,cn=users,dc=company,dc=com (56819d8c-9438-103b-9ea1-cff9eabf22b5; users/user; tasks:1) now has an error count of 906Task ID: 1


Solution

Step 1: Unblock the Sync Queue Manually

Move the failing item out of the active tasks queue and into the morgue table to allow subsequent pending changes to process.

univention-ox-connector-task-management move-task-to-morgue --task-id=1 --error-msg="Failure of Task 1 - has an error count of 906"

After the move from the Task, the queue should be processed again, thus ensuring synchronization. Otherwise, a restart of the listener service from the ox-connector could help:

systemctl restart univention-appcenter-listener-converter@ox-connector.service

Step 2: Configure Automatic Failover (Preventative Measure)

To prevent future synchronization lockups caused by singular invalid records or unresolvable deletion states, flip the default error behavior to False.

If you now manually set the configuration to the value “False”, the ox-connector will try to process the task 5 times on a next problem, and if that is not executed successfully, the task will be moved to morgue by the ox-connector. This prevents the queue from being blocked.

You can use the following command to change the configuration, and the connector will then be restarted:

univention-app configure ox-connector --set OX_CONNECTOR_STOP_ON_ERROR=False

Advanced Management: Cleaning Up the Morgue via SQLite

The sqlite way to remove a task from the morgue table.

  1. Install the SQLite CLI tool if not already present:
apt install sqlite3
  1. Access the connector’s internal database:
sqlite3 /var/lib/univention-appcenter/apps/ox-connector/data/listener/ox-connector.db
  1. Inspect and query the database content:
sqlite> .tables
morgue     old        relations  tasks

sqlite> SELECT * FROM morgue;
1|f2a4d314-2d17-4e27-bc4d-be5962c56c98|oxmail/shared_account|cn=fupo4,dc=ucs,dc=test|{"mailPrimaryAddress": "fupo4@as8-oxc-test.demo.open-xchange.com", "name": "fupo4", "univentionObjectIdentifier": "f2a4d314-2d17-4e27-bc4d-be5962c56c98", "users": []}|No|2026-04-21 11:34:47.353551
2|2d43f385-3a15-42d2-8b8c-c1eddfaa753a|oxmail/shared_account|cn=fupo5,dc=ucs,dc=test|{"contextid": "333", "mailPrimaryAddress": "fupo5@as8-oxc-test.demo.open-xchange.com", "name": "fupo5", "univentionObjectIdentifier": "2d43f385-3a15-42d2-8b8c-c1eddfaa753a"}|No|2026-04-21 12:33:11.958356
<skip>
  1. Delete the invalid record using its unique object identifier (obj_id):
sqlite> DELETE FROM morgue WHERE obj_id = 'f2a4d314-2d17-4e27-bc4d-be5962c56c98';
  1. Cross-check your changes:
sqlite> SELECT * FROM morgue;
4|5248470d-7900-49bb-b3a6-da4b79d1e849|oxmail/shared_account|cn=fupo8,dc=ucs,dc=test|{"mailPrimaryAddress": "fupo8@as8-oxc-test.demo.open-xchange.com", "name": "fupo8", "oxContext": "333", "univentionObjectIdentifier": "5248470d-7900-49bb-b3a6-da4b79d1e849"}|No|2026-04-21 14:26:02.305375
5|5248470d-7900-49bb-b3a6-da4b79d1e849|oxmail/shared_account|cn=fupo8,dc=ucs,dc=test|{"mailPrimaryAddress": "fupo8@as8-oxc-test.demo.open-xchange.com", "name": "fupo8", "oxContext": "333", "univentionObjectIdentifier": "5248470d-7900-49bb-b3a6-da4b79d1e849", "users": [["9dfb0203-5f71-4083-a0d4-e209db1ad3af", "370c3e56-e181-478d-8b04-179a91912541"]]}|No|2026-04-21 14:26:23.427178

References