Port 389 is LDAP in plaintext, 636 is LDAPS, and 3268 and 3269 are the Active Directory global catalog. Encryption decides 389 against 636. Scope decides one domain against the whole forest. Almost every application should be on 636.
- Port 389 sends the bind credentials in plaintext
- Port 636 is TLS from the first byte, so a failure is a failure
- Ports 3268 and 3269 search the forest, with partial attributes
- STARTTLS on 389 is only as good as a client that refuses to continue
- Anonymous binds let anyone who reaches the port read the directory
On this page
The protocolWhat an LDAP port actually carries
IANA registers port 389 to the Lightweight Directory Access Protocol, on TCP and on UDP. That protocol reads and writes a directory service, which is a database of entries about users, groups, computers and printers, arranged as a tree instead of as tables.
The directory is shared infrastructure. Mail, VPN, Wi-Fi, file shares and every application that does not keep its own user list ask the same directory server the same questions, which is why one wrong port setting turns into a support queue rather than a single broken service.
Every entry has a distinguished name, its full path through that tree, written in the style of CN=jsmith,OU=People,DC=example,DC=com. An application configured against LDAP needs one of those names as its base, the point in the tree where its searches begin.
The same protocol operations travel over all four ports. RFC 4511, the specification for LDAP version 3, defines them, and an integration normally uses a handful.
| Operation | What it does |
|---|---|
| Bind | Authenticates the session, or opens it anonymously |
| Search | Returns entries under a base name that match a filter |
| Compare | Tests whether an entry holds a given value |
| Modify, Add, Delete | Change directory data, for management tools |
| StartTLS | Asks the server to upgrade the connection to TLS |
| Unbind | Ends the session |
A search names three things: the base entry, a scope, and a filter. RFC 4511 gives the scope three values, the base entry alone, the level immediately below it, or the whole subtree. A filter looks like (sAMAccountName=jsmith). The reply is entries with their attributes.
That reply is the reason the choice of LDAP port is a security decision and not a formality. On an unencrypted port, the bind credentials, the filter and every attribute returned are readable by anything on the network path between the application and the directory server.
Two decisionsThe two decisions, which are not the same decision
Choosing an LDAP port confuses people because two independent questions get collapsed into one.
Is the connection encrypted? Access on port 389 is plaintext. Port 636 is TLS from the first byte, before any protocol exchange with the server happens at all. That is the security decision, and it applies equally to the global catalog ports: 3268 plaintext, 3269 encrypted.
What is the scope of the question? Ports 389 and 636 talk to a directory server about its own domain, and they return every attribute of every user and object in it. Ports 3268 and 3269 talk to the global catalog, which holds a partial copy of every object in the entire forest.
Those two axes produce the four ports, and the table below is the whole thing.
| Port | Encrypted | Scope | Attributes returned |
|---|---|---|---|
| 389 | No | One domain | All of them |
| 636 | Yes, TLS from the start | One domain | All of them |
| 3268 | No | The whole forest | A partial set |
| 3269 | Yes, TLS from the start | The whole forest | A partial set |
The attribute column is the row that catches people. The global catalog is fast and forest-wide because it stores only a subset of the data, so an application that queries 3268 for an attribute outside that subset gets an empty result rather than an error.
Configuring an application against 3268 and finding that a user field is always blank is almost always this.
LDAPS or STARTTLSLDAPS against STARTTLS, which are not the same
Two mechanisms encrypt LDAP and they work differently.
LDAPS on port 636, LDAP over SSL in the older naming, establishes TLS before any LDAP traffic, in the same way HTTPS does on port 443. The connection to the server is encrypted or it fails. There is no window in which any data is in plaintext.
STARTTLS on port 389 opens a plaintext connection to the server and then issues an extended operation asking to upgrade it to TLS. It reaches the same place by a different route, and it has one weakness: the client has to insist.
A client that connects, is told the upgrade is unavailable, and continues in plaintext has silently done exactly what the encryption was meant to prevent.
Both are acceptable when configured strictly. LDAPS is easier to be certain about, because a misconfiguration produces a failed connection rather than a working plaintext one, and that is the practical argument for preferring port 636.
Why 389 is badWhy plaintext 389 is worse than it looks
An unencrypted LDAP bind sends the credentials in the clear. That single fact is the reason this port has a reputation, and there are three specific consequences.
A simple bind is a password on the wire. Anyone positioned to capture traffic on that network segment has the user account, and the service accounts configured for LDAP access are frequently privileged in ways nobody intended.
Directory data is readable in transit. LDAP queries and the information they return carry user names, group memberships, email addresses and often much more. That is a description of an organization, and it is valuable to an attacker on its own, before any account is compromised.
Anonymous access may be permitted. LDAP allows an anonymous bind, a connection with no credentials at all, and a directory server that still permits anonymous reads will answer questions from anybody who can reach port 389.
Active Directory restricts this by default and other directory servers do not always, and a legacy application is the usual reason somebody turned it back on. Anonymous access plus a reachable port is directory enumeration with no attack required.
Microsoft has been closing this down. LDAP signing and channel binding requirements have been tightened repeatedly, and a directory server configured to require signing will refuse unsigned simple binds on port 389. Applications that quietly worked for a decade lose access, and the error rarely says why.
That last point is worth planning around rather than discovering. Any application still configured against 389 with a simple bind is on borrowed time, and the fix is to move it to 636 before a hardening change makes the decision for you.
Which to useWhich port an application should use
The default in almost every application's configuration field is 389, and it is almost never the right answer.
Use 636 for authentication and for anything with a credential. LDAPS, one domain, all attributes. This covers the overwhelming majority of application integrations, from VPN authentication to a printer's address book.
Use 3269 when the query has to cross domains. A forest with several domains and an application that needs to find users anywhere in it needs the global catalog, encrypted. Check the attributes it needs are in the partial set first.
Use 389 only inside a boundary you control completely, for a service that carries no credentials and reads no sensitive data. That set is smaller than it sounds, and anonymous access should be off on the server either way.
Never use any of them across the internet. A directory server is not an internet-facing service, whichever port is involved. Exposing it exposes the organization chart at minimum and every user account at worst, and that is true on all four of these ports equally.
When it failsWhat to check when an LDAP integration fails
Confirm which port the application is actually using. The field says 389 by default and people change the hostname without noticing the port.
Test the port itself before the credentials. An LDAPS connection that fails to open is a certificate or a firewall, not a password.
Check the certificate on 636. LDAP over SSL requires the client to trust the certificate the server presents. A self-signed or expired certificate, or a hostname that does not match, produces a connection failure that looks exactly like an authentication failure.
If an attribute is always empty, check the port. Port 3268 returns a partial attribute set. Move to 636 and the attribute usually appears.
If it broke without a change on your side, suspect signing. A domain controller hardening update that requires signing will break unsigned binds on 389 with no warning and no useful message.
PitfallsWhere people go wrong
Leaving the port at 389 because the field was prefilled. It is a default, not a recommendation, and it sends the bind credentials in plaintext.
Believing STARTTLS on 389 is equivalent to LDAPS. It reaches the same place only if the client refuses to continue without the upgrade, and many clients do not refuse.
Using 3268 for authentication. The global catalog is for searching the forest. Authenticating a user belongs on 636 against a directory server for that domain.
Blaming the credentials when LDAPS will not connect. Certificate trust and firewall rules produce failures that look identical to a wrong password from inside the application.
Opening LDAP to the internet for a cloud application. Use a directory synchronization service or a VPN. A directory reachable from the internet is an enumeration target, and it always has been.
Assuming an empty attribute means an empty field. On the global catalog it usually means that data is not replicated there at all.
Leaving anonymous access enabled for one legacy application. Anybody who can reach the port can then read the directory. Give that application an account and turn anonymous binds off.
ComparisonFour ports, and the row that is the same for all of them
| Criterion | 389 | 636 | 3268 | 3269 |
|---|---|---|---|---|
| Encrypted | No | Yes, from the start | No | Yes, from the start |
| Scope | One domain | One domain | The forest | The forest |
| All attributes | Yes | Yes | No, a partial set | No, a partial set |
| Right for authentication | No | Yes | No | Acceptable |
| Right for a forest search | No | No | Only inside a trusted network | Yes |
| Safe from the internet | No | No | No | No |
The last row is the same for all four, and it is worth stating because the encryption column tempts people to treat 636 as internet-safe. TLS protects the traffic and does nothing about the fact that a directory answers questions about every person in the organization.
FAQFrequently asked questions
What is the default LDAP port?
389, on TCP and UDP, and it is unencrypted. Most application configuration fields default to it, which is why so many integrations run in plaintext.
What port does LDAPS use?
636. TLS is established before any LDAP traffic, so the connection is encrypted from the first byte or it does not open at all.
What are ports 3268 and 3269 for?
The Active Directory global catalog, which answers queries about the whole forest rather than one domain. 3268 is plaintext and 3269 is the encrypted version.
What is the difference between 389 and 3268?
Scope and attributes. Port 389 asks a domain controller about its own domain and returns every attribute. Port 3268 asks the global catalog about the whole forest and returns only a partial attribute set.
Is port 389 secure?
No. A simple bind on it sends the user credentials in plaintext, and the directory data returned travels in the clear as well.
What is an anonymous LDAP bind?
A connection to the server with no credentials at all. Where the directory permits it, anybody who can reach port 389 can read the information it holds, which is why it should be disabled.
What is STARTTLS?
An extended operation that upgrades a plaintext connection on port 389 to TLS. It is only as safe as the client's willingness to refuse the connection when the upgrade is unavailable.
Is STARTTLS as good as LDAPS?
When configured strictly, yes. LDAPS is easier to be certain about, because a misconfiguration fails to connect rather than silently continuing in plaintext.
Which port should my application use?
636 in almost every case. Use 3269 if the query has to span domains in a forest, and check that the attributes you need exist in the global catalog.
Why is an attribute always empty on 3268?
Because the global catalog holds only a partial set of attributes. The query succeeds and the field comes back blank. Use 636 against a domain controller instead.
Why did my LDAP integration suddenly stop working?
Often a domain controller change requiring LDAP signing or channel binding, which breaks unsigned simple binds on 389. Moving to 636 is the fix and the long-term answer.
Can I use LDAP over the internet?
No, on any of these ports. Use directory synchronization services or a VPN. A reachable directory server is an enumeration target regardless of encryption.
Do I need a certificate for LDAPS?
Yes. The server needs a certificate the client trusts, with a matching name. Certificate problems are the commonest reason an LDAP over SSL connection fails.
Is LDAP the same as Active Directory?
No. LDAP is the protocol, and Active Directory is one of the directories that speaks it. OpenLDAP and other directories use the same ports.
What else does a domain controller need open?
Kerberos on 88, DNS on 53, SMB on 445 for group policy, and RPC on 135 plus a dynamic port for management operations.
Keep readingRelated concepts
Read next · Ports Port 88, and Why a Domain Stops Working Without It The authentication port a domain also needs, and the one that fails differently when a firewall is in the way. Open this next10 min- Directory and identity · 13 min LDAP Explained The protocol these ports carry, and what a directory actually is before any of this matters.
- Ports · 10 min Port 135, the Endpoint Mapper, and the Ports It Points At The third port a domain controller needs open, and the only one that hands out a second port number.