Problem: UCS Office 365 Connector MSGraphError - HTTP Response Status 404

Problem

Users are no longer synchronized reliably between Univention Corporate Server (UCS) and Microsoft Entra ID, formerly Azure Active Directory.

After a user is created in UCS, the account appears in Entra ID. However, subsequent synchronization fails, and the connector appears unable to associate the UCS user with the existing Entra ID account.

The connector log shows :

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/univention/listener/api_adapter.py", line 132, in _handler
    self._module_handler.modify(dn, old, new, self._saved_old_dn if self._rename else None)
  File "/usr/lib/univention-directory-listener/system/office365-user.py", line 51, in modify
    self.connector.modify(new_udm_user=new_udm_user, old_udm_user=old_udm_user)
  File "/usr/lib/python3/dist-packages/univention/office365/connector/connector.py", line 607, in modify
    self.new_or_reactivate_user(new_udm_user, core)
  File "/usr/lib/python3/dist-packages/univention/office365/connector/connector.py", line 457, in new_or_reactivate_user
    user_azure.create_or_modify()
  File "/usr/lib/python3/dist-packages/univention/office365/microsoft/objects/azureobjects.py", line 346, in create_or_modify
    user_azure = self.get(self._core, self.userPrincipalName)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/univention/office365/microsoft/objects/azureobjects.py", line 428, in get
    response = core.get_user(object_id, selection=','.join(selection) if selection else None)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/univention/office365/microsoft/core.py", line 121, in get_user
    return self._call_graph_api('GET', URLs.users(path=user_id, params=selection), expected_status=[200])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/univention/office365/microsoft/core.py", line 691, in _call_graph_api
    raise typecast_error_into_child_class(error)
univention.office365.microsoft.exceptions.core_exceptions.MSGraphError: HTTP response status: 404

Root Cause

In the reported environment, the customer identified NGINX bot protection on an OPNsense system as the source of connectivity problems. According to the customer, the protection mechanism blocked Python-based requests and retained IP addresses on a blocklist. Connectivity was intermittent, depending on the Microsoft destination contacted.

This explanation is specific to the reported deployment. The HTTP 400 and 404 responses alone do not establish a firewall or bot-protection issue. Both requests shown in the log reached Microsoft Graph and received application-level responses. Earlier or additional blocked requests are not visible in this excerpt.

NGINX normally handles incoming reverse-proxy traffic rather than outbound UCS connections. Before applying this diagnosis elsewhere, verify that the affected communication actually passes through the identified protection mechanism.


Solution

1. Identify the blocked traffic

Review OPNsense, NGINX, and any associated security logs around the synchronization failure.

Confirm:

  • Which requests were blocked.
  • Which protection rule triggered the block.
  • Whether the affected addresses are source or destination addresses.
  • How the affected UCS-to-Microsoft communication traverses the security component.

Correlate these events with the connector log timestamps. Do not assume that every UPN conflict or HTTP 404 has this cause.

2. Correct the security policy

If legitimate connector traffic is being blocked:

  • Adjust the responsible rule or configure a narrowly scoped exception.
  • Remove related blocklist entries after correcting the rule that generated them.
  • Ensure that required Microsoft authentication and API connections remain accessible.

Avoid disabling bot protection globally. Do not rely solely on a Python user agent as a trust criterion or on individual Microsoft IP addresses as a permanent workaround.

3. Verify synchronization

After correcting connectivity:

  1. Create a dedicated test user in UCS with Microsoft 365 synchronization enabled.
  2. Confirm that the account appears in the intended Entra ID tenant.
  3. Change a synchronized attribute, such as the display name, in UCS.
  4. Confirm that the same Entra ID account is updated.
  5. Check that neither the connector nor the security component records further related failures.

Successful initial creation alone is insufficient: subsequent updates must also work reliably.

If errors persist, investigate the connector’s stored account mapping, the configured tenant, and the conflicting Entra ID object. Do not delete accounts or clear synchronization metadata solely on the basis of these messages.