passbolt/passbolt_api · error · BadRequestException
The directory structure cannot be retrieved.
Error message
The directory structure cannot be retrieved.
What it means
Thrown by the DirectorySettingsController::test() endpoint when converting the LDAP directory tree (getTree()) to an array for the API response fails. This endpoint runs a dry-run of the LDAP configuration against the live directory and returns users, groups and their hierarchy; a failure here means the tree data returned by the LDAP connection was inconsistent or an exception occurred while serializing it.
Solutions
- Read the appended $e->getMessage() in the response body to identify the underlying serialization/tree error
- Check the LDAP directory for broken group memberships or orphaned entries (groups whose parent DN does not exist)
- Re-run the test endpoint after fixing LDAP data; compare with a fresh ldapsearch output
- If triggered by specific users/groups, exclude them via filters in the LDAP settings and re-test
Example fix
// before: broken tree from cyclic group membership groupOfNames -> memberOf -> groupOfNames (cycle) // after: remove the cycle or filter the offending group in the LDAP filter settings 'groupFilter' => '(&(objectClass=groupOfNames)(!(memberOf=<bad-parent-dn>)))'
Defensive patterns
Strategy: try-catch
Validate before calling
// client-side pre-check before calling the test endpoint
if (!settings.ldap.host || !settings.ldap.port) throw new Error('LDAP host/port required'); Type guard
$tree = $filteredDirectoryResults->getTree();
if (!is_array($tree)) {
throw new BadRequestException('Directory tree is not a traversable structure.');
} Try / catch
try {
$res = await api.post('/directorysync/settings/test', settings);
} catch (e) {
if (e.message.includes('directory structure cannot be retrieved')) {
logLdapTreeIssue(e.message); // underlying cause appended after the message
}
} Prevention
- Keep LDAP group parent relationships consistent (no cycles, no orphaned groups)
- Test LDAP config with the /settings/test endpoint before saving
- Filter out malformed entries via LDAP filter settings
- Monitor logs/error.log for recurring tree serialization warnings
When it happens
Trigger: POST /directorysync/settings/test with valid LDAP settings where the resulting FilteredDirectoryResults object's getTree() throws during _toArray() — e.g. malformed group memberships, entries referencing missing parents, or LDAP attributes in unexpected formats.
Common situations: LDAP servers with cyclic or broken group parent relationships; partially migrated AD/LDAP trees; entries deleted between the fetch of users/groups and the tree build; custom LDAP schemas producing unexpected attribute types.
Related errors
- There was an issue while retrieving the invalid entries.
- group(s) returned by your directory are invalid and will be…
- users returned by your directory are invalid and will be…
- An error has occurred parsing groupCustomFilter
- An error has occurred parsing userCustomFilter
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/9caec05b5d9d7b54.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/DirectorySync/src/Controller/DirectorySettingsController.php:146
try {
$settings = LdapConfigurationForm::formatFormDataToOrgSettings($data);
$orgSettings = new DirectoryOrgSettings($settings);
$directory = DirectoryFactory::get($orgSettings);
$filteredDirectoryResults = $directory->getFilteredDirectoryResults();
$outputData = [
'users' => $this->_toArray(array_values($filteredDirectoryResults->getUsers())),
'groups' => $this->_toArray(array_values($filteredDirectoryResults->getGroups())),
];
} catch (Exception $e) {
throw new BadRequestException('The users and groups cannot be retrieved. ' . $e->getMessage());
}
try {
$outputData['tree'] = $this->_toArray($filteredDirectoryResults->getTree());
} catch (Exception $e) {
$msg = __('The directory structure cannot be retrieved.');
throw new BadRequestException($msg . ' ' . $e->getMessage());
}
try {
$invalidObjects = $filteredDirectoryResults->getInvalidGroups();
$invalidObjects = array_merge($invalidObjects, $filteredDirectoryResults->getInvalidUsers());
$outputData['errors'] = $this->_toArray($invalidObjects);
} catch (Exception $e) {
$msg = __('There was an issue while retrieving the invalid entries.');
throw new BadRequestException($msg . ' ' . $e->getMessage());
}
$this->success(__('The operation was successful.'), $outputData);
}
/**
* Disable the ldap integration.
*
* @return voidView on GitHub (pinned to 31c1bbc10f)