juicedata/juicefs · error

ldap_bind_sW failed

Error message

ldap_bind_sW failed: %d

What it means

After ldap_initW succeeds, LdapConnect enables signing/encryption options and performs an anonymous Negotiate bind via ldap_bind_sW. If the bind result is not LDAP_SUCCESS, the handle is unbound and "ldap_bind_sW failed: %d" is returned with the LDAP status code. The numeric code identifies the exact bind failure (e.g. 49 invalid credentials, 81 server down).

Solutions

  1. Look up the returned LDAP code (e.g. 49=invalid credentials, 81=server down) and address it specifically.
  2. Confirm the machine is domain-joined and its secure channel is healthy (Test-ComputerSecureChannel).
  3. Ensure the LDAP signing/encryption requirements of the DC match the client options set in LdapConnect.
  4. Check system time skew against the domain controller.

Example fix

// diagnostic: capture the code
if int32(r1) != LDAP_SUCCESS {
    return 0, fmt.Errorf("ldap_bind_sW failed: %d", r1) // 49 -> fix creds; 81 -> network
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-check machine secure channel (PowerShell): Test-ComputerSecureChannel
// pre-check time skew: w32tm /stripchart /computer:dc.domain.local

Try / catch

var handle uintptr
var err error
for i := 0; i < 3; i++ {
    handle, err = LdapConnect("")
    if err == nil { break }
    time.Sleep(time.Duration(i+1) * time.Second)
}

Prevention

When it happens

Trigger: ldap_bind_sW returns a non-zero LDAP result: DC rejects the Negotiate authentication, machine account issues, TLS/signing requirements unmet, or the DC became unreachable between init and bind.

Common situations: Running on a non-domain-joined machine where Negotiate falls back to anonymous and the DC refuses; expired machine account password; DC requiring LDAP signing the client can't provide; clock skew breaking Kerberos.

Related errors


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

Appendix: source

Thrown at pkg/win/ldap.go:74

func LdapConnect(host string) (uintptr, error) {
	hostPtr, err := windows.UTF16PtrFromString(host)
	if err != nil {
		return 0, err
	}
	handle, _, _ := procLdapInitW.Call(
		uintptr(unsafe.Pointer(hostPtr)),
		uintptr(LDAP_PORT),
	)
	if handle == 0 {
		return 0, fmt.Errorf("ldap_initW failed")
	}
	procLdapSetOptionW.Call(handle, uintptr(LDAP_OPT_SIGN), uintptr(LDAP_OPT_ON))
	procLdapSetOptionW.Call(handle, uintptr(LDAP_OPT_ENCRYPT), uintptr(LDAP_OPT_ON))

	r1, _, _ := procLdapBindSW.Call(handle, 0, 0, uintptr(LDAP_AUTH_NEGOTIATE))
	if int32(r1) != LDAP_SUCCESS {
		procLdapUnbind.Call(handle)
		return 0, fmt.Errorf("ldap_bind_sW failed: %d", r1)
	}
	return handle, nil
}

func LdapClose(handle uintptr) {
	procLdapUnbind.Call(handle)
}

func LdapGetValue(
	handle uintptr,
	base string,
	scope uint32,
	filter string,
	attribute string,
) (string, error) {
	var basePtr *uint16
	if base != "" {
		p, err := windows.UTF16PtrFromString(base)

View on GitHub (pinned to c9a67b23e8)