Use paged (RFC 2696) LDAP search for the directory-wide import browse

A plain ldapsearch against this AD with the identical broad filter
(objectClass=person) completed cleanly — 996 entries, exit 0 — ruling
out the network/server as the cause of the "<id> closed" ConnectionError
our app was hitting. The difference is response size: ~1000 LDAP protocol
messages in one unbounded response is apparently enough to trip up
ldapjs's client-side handling, even though our own busy_timeout increase
(previous commit) didn't help since the connection was being closed, not
timed out. Paging the search (200 entries per round-trip, handled
internally by ldapjs — callers still just see one continuous stream of
searchEntry events) sidesteps the issue regardless of its exact root
cause. Applies to both the admin "import accounts" browse and the
per-login user lookup, since they share the same search() helper.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012o9j9RezxbZVKQMrB7oRLY
This commit is contained in:
ogrechkoandClaude Sonnet 5 committed 2026-08-05 10:45:52 +00:00
1 parent 12e547d71e
commit a40723b61b
1 file changed
+9 -1
+9 -1
View File
@@ -45,7 +45,15 @@ function search(
): Promise<{ dn: string; attributes: Record<string, string> }[]> {
return new Promise((resolve, reject) => {
const results: { dn: string; attributes: Record<string, string> }[] = [];
client.search(baseDn, { filter, scope: "sub" }, (err, res) => {
// Paged (RFC 2696) rather than one unbounded response: a directory-wide
// browse on a real AD domain can return ~1000 entries, and ldapjs's
// single-response handling for a batch that size was observed to drop
// the connection ("<id> closed") even though a plain `ldapsearch` with
// the identical filter completes cleanly — so the fix is on our client's
// response handling, not the query itself. ldapjs runs the multi-page
// RFC 2696 round-trips internally; callers still just see one continuous
// stream of `searchEntry` events followed by a single `end`.
client.search(baseDn, { filter, scope: "sub", paged: { pageSize: 200 } }, (err, res) => {
if (err) {
reject(err);
return;