AD Connection Errors
Diagnose and fix Active Directory and LDAP connection issues.
LDAP Bind Failed
Error Messages
LDAP error 49: invalid credentialsLDAP bind failed: wrong passwordunable to bind to LDAP server
Solutions
- Verify credentials:
$cred = Get-Credential -UserName "svc_adunlock@company.local"
Get-ADUser -Identity svc_adunlock -Server dc01.company.local -Credential $cred- Check UPN format:
# Use UPN format
service_account: "svc_adunlock@company.local"
# Or DOMAIN\user format
service_account: "COMPANY\\svc_adunlock"- Check account status:
Get-ADUser -Identity svc_adunlock -Properties LockedOut, Enabled, PasswordExpiredConnection Refused / Timeout
Error Messages
connection refuseddial tcp: i/o timeoutno route to host
Solutions
- Check connectivity:
Test-NetConnection -ComputerName dc01.company.local -Port 636- Check firewall:
# On DC
Get-NetFirewallRule -DisplayName "*LDAP*" | Select-Object DisplayName, Enabled- Verify DC hostname:
Resolve-DnsName dc01.company.localCertificate Errors
Error Messages
certificate signed by unknown authorityx509: certificate has expiredTLS handshake failed
Solutions
- Check DC certificate:
$ldapServer = "dc01.company.local"
$port = 636
$tcpClient = New-Object System.Net.Sockets.TcpClient
$tcpClient.Connect($ldapServer, $port)
$sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream())
$sslStream.AuthenticateAsClient($ldapServer)
$cert = $sslStream.RemoteCertificate
Write-Host "Subject: $($cert.Subject)"
Write-Host "Expires: $($cert.GetExpirationDateString())"
$sslStream.Close()
$tcpClient.Close()-
If certificate expired: Request new certificate for DC
-
If self-signed: Add to trusted store or configure connector to skip verification (not recommended for production)
Permission Denied
Error Messages
access deniedinsufficient rightsLDAP error 50: insufficient access
Solutions
- Verify delegated permissions:
dsacls "OU=Users,DC=company,DC=local" | Select-String "svc_adunlock"-
Re-run permissions script: See Permissions Script
-
Check on correct OU: Permissions must be on the OU containing users, not the user itself.
User Not Found
Error Messages
user not found in directoryno entries returnedobject not found
Solutions
- Check base DN:
base_dn: "DC=company,DC=local" # Must match your domain- Check allowed OUs:
allowed_ous:
- "OU=Users,DC=company,DC=local" # Exact DN, case-sensitive- Verify user exists in OU:
Get-ADUser -Filter "sAMAccountName -eq 'testuser'" | Select-Object DistinguishedName
# Verify the OU matches allowed_ousPassword Reset Fails
Error Messages
unwilling to performLDAP error 53constraint violation
Causes and Solutions
| Cause | Solution |
|---|---|
| Not using LDAPS | Enable port 636 and tls_mode: ldaps |
| Password doesn’t meet policy | Password generated meets complexity requirements |
| User can’t change password | Check “User cannot change password” in AD |
| Password recently changed | Wait for minimum password age |
Verify LDAPS:
ad:
port: 636
tls_mode: ldapsAccount Not Unlocking
Error Messages
unable to unlock accountwrite lockoutTime failed
Solutions
- Verify permission:
dsacls "OU=Users,DC=company,DC=local" | Select-String "lockoutTime"- Check if account is actually locked:
Get-ADUser -Identity testuser -Properties LockedOut- Test manual unlock:
Unlock-ADAccount -Identity testuser -Credential (Get-Credential)Search Returns Too Many/Few Results
Solutions
- Check base DN scope:
base_dn: "DC=company,DC=local" # Searches all sub-OUs
# Or more specific:
base_dn: "OU=Users,DC=company,DC=local" # Only this OU-
Verify allowed_ous filter: Only users in allowed_ous can use self-service.
-
Check search attributes: The connector searches by sAMAccountName, mail, and telephoneNumber.
Quick Diagnostic Script
# Run this to diagnose AD issues
param(
[string]$DC = "dc01.company.local",
[string]$ServiceAccount = "svc_adunlock@company.local"
)
Write-Host "AD Connection Diagnostic" -ForegroundColor Cyan
# Test connectivity
Write-Host "`n1. Testing LDAPS connectivity..."
$result = Test-NetConnection -ComputerName $DC -Port 636 -WarningAction SilentlyContinue
if ($result.TcpTestSucceeded) {
Write-Host " ✅ Port 636 reachable" -ForegroundColor Green
} else {
Write-Host " ❌ Port 636 not reachable" -ForegroundColor Red
}
# Test certificate
Write-Host "`n2. Testing SSL certificate..."
try {
$tcpClient = New-Object System.Net.Sockets.TcpClient
$tcpClient.Connect($DC, 636)
$sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream())
$sslStream.AuthenticateAsClient($DC)
$cert = $sslStream.RemoteCertificate
$expires = [DateTime]::Parse($cert.GetExpirationDateString())
if ($expires -gt (Get-Date)) {
Write-Host " ✅ Certificate valid until $expires" -ForegroundColor Green
} else {
Write-Host " ❌ Certificate EXPIRED on $expires" -ForegroundColor Red
}
$sslStream.Close()
$tcpClient.Close()
} catch {
Write-Host " ❌ SSL error: $_" -ForegroundColor Red
}
# Test credentials
Write-Host "`n3. Testing service account..."
try {
$cred = Get-Credential -UserName $ServiceAccount -Message "Enter service account password"
Get-ADUser -Identity ($ServiceAccount -split '@')[0] -Server $DC -Credential $cred | Out-Null
Write-Host " ✅ Credentials valid" -ForegroundColor Green
} catch {
Write-Host " ❌ Credential error: $_" -ForegroundColor Red
}
Write-Host "`nDiagnostic complete." -ForegroundColor CyanLast updated on