client.bind() performs the LDAP bind operation described in Bind and authentication. It's usually the first call you make on a fresh client.
import ldap from "ldapjs";
const client = ldap.createClient({ url: "ldaps://dc1.example.com:636" });
client.bind(
"CN=svc-app,OU=Service Accounts,DC=example,DC=com",
process.env.LDAP_BIND_PASSWORD!,
(err) => {
if (err) {
console.error("Bind failed:", err.message);
return;
}
console.log("Bound as service account");
},
);
The first argument is the bind DN, not a username — you need the full distinguished name of the entry you're authenticating as. If you only have a username, you typically bind as a service account first, search for the user's DN, then bind again as that DN (see Authentication with ldapjs).
A failed bind comes back as an error on the callback, not a thrown exception. The error's code matches the standard LDAP result codes:
client.bind(bindDn, password, (err) => {
if (err) {
if (err.name === "InvalidCredentialsError") {
console.log("Wrong username or password");
} else {
console.log("Bind error:", err.message);
}
return;
}
// proceed
});
Active Directory often includes extra detail in the error message beyond the bare result code — things like "password expired" or "account locked out" show up as an extended data code appended to the message.
LDAP Error Decoder
Paste a raw error string in to see exactly what it means.
Calling bind() with an empty DN and password performs an anonymous bind, if the server allows it:
client.bind("", "", (err) => {
// ...
});
Always unbind when you're done with a client, especially for short-lived connections (like one per HTTP request):
client.unbind();
For long-lived, reused clients (a shared service-account connection), you typically bind once at startup and keep the connection open rather than binding per-request.
Once bound, you can start looking up entries: Searching.