juicedata/juicefs · error

ldap_search_sW failed: %d

Error message

ldap_search_sW failed: %d

What it means

LdapGetValue issues ldap_search_sW against the connected directory with the given base DN, filter, and attribute list. If the search call returns a non-LDAP_SUCCESS result, it returns "ldap_search_sW failed: %d" with the LDAP status code. Used by LdapGetDefaultNamingContext and LdapGetTrustPosixOffset during trust-POSIX-offset initialization.

Source

Thrown at pkg/win/ldap.go:119

	}
	attrPtr, err := windows.UTF16PtrFromString(attribute)
	if err != nil {
		return "", err
	}
	attrs := []uintptr{uintptr(unsafe.Pointer(attrPtr)), 0}

	var msg uintptr
	r1, _, _ := procLdapSearchSW.Call(
		handle,
		uintptr(unsafe.Pointer(basePtr)),
		uintptr(scope),
		uintptr(unsafe.Pointer(filterPtr)),
		uintptr(unsafe.Pointer(&attrs[0])),
		0,
		uintptr(unsafe.Pointer(&msg)),
	)
	if int32(r1) != LDAP_SUCCESS {
		return "", fmt.Errorf("ldap_search_sW failed: %d", r1)
	}
	defer procLdapMsgFree.Call(msg)

	entry, _, _ := procLdapFirstEntry.Call(handle, msg)
	if entry == 0 {
		return "", fmt.Errorf("no entries found")
	}
	vals, _, _ := procLdapGetValuesW.Call(handle, entry, uintptr(unsafe.Pointer(attrPtr)))
	if vals == 0 {
		return "", fmt.Errorf("no attribute values")
	}
	defer procLdapValueFreeW.Call(vals)
	cnt, _, _ := procLdapCountValuesW.Call(vals)
	if cnt == 0 {
		return "", fmt.Errorf("no attribute values")
	}
	firstPtr := *(*uintptr)(unsafe.Pointer(vals))
	value := windows.UTF16PtrToString((*uint16)(unsafe.Pointer(firstPtr)))

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Decode the LDAP status code (e.g. 32=no such object, 50=insufficient rights) and act on it.
  2. Verify the base DN and filter strings, especially escaping of special characters.
  3. Run under an account with rights to read trustedDomain objects in the Configuration NC.
  4. Reconnect (LdapClose + LdapConnect) if the session may have timed out.

Example fix

// before
r1, _, _ := procLdapSearchSW.Call(...)
if int32(r1) != LDAP_SUCCESS {
    return "", fmt.Errorf("ldap_search_sW failed: %d", r1)
}
// after (caller-side retry on transient codes)
if int32(r1) == 81 || int32(r1) == 85 { // server down / busy
    handle, err = LdapConnect(host); /* retry once */
}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate filter/base before calling
if baseDN == "" || !strings.Contains(filter, "=") {
    return errors.New("invalid LDAP base DN or filter")
}

Try / catch

val, err := LdapGetDefaultNamingContext(handle)
if err != nil {
    var code int
    if n, _ := fmt.Sscanf(err.Error(), "ldap_search_sW failed: %d", &code); n == 1 {
        log.Printf("ldap search status %d", code) // 32=bad DN, 50=rights
    }
    return err
}

Prevention

When it happens

Trigger: ldap_search_sW returns an error status: bad base DN (e.g. wrong defaultNamingContext), insufficient rights to read the trustedDomain objects, size/scope limits, or the DC dropped the connection.

Common situations: Querying CN=Configuration or trusted domain objects with an account lacking read permission; malformed LDAP filter; base DN with unescaped special characters; expired session after long idle.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/56692e8d5441fcb8. Report an issue: GitHub.