Diagnosing LDAP Authentication Failures in Forgejo: A Step‑by‑Step Guide
Step‑by‑step diagnosis of LDAP login problems in Forgejo, covering connectivity, bind credentials, search base, attribute mapping, TLS trust, and group configuration.
03 Apr 2026, 03:20 UTC

Recognizable condition
When a user tries to log in with LDAP credentials, Forgejo shows an "Invalid credentials" message and the Forgejo log contains LDAP‑related errors such as:
LDAP bind failed: Invalid credentialsLDAP search error: No such objectTLS handshake failureGroup lookup failed
The exact log location is set by the [log] section in app.ini (default log/forgejo.log). If you have overridden ROOT_PATH or LOG_ROOT_PATH, adjust the path accordingly.
Short cause/diagnostic table
| Possible cause | Typical symptom in logs |
|---|---|
| Network unreachable / wrong host/port | Connection timed out or refused |
| Incorrect bind DN or password | LDAP bind failed: Invalid credentials |
| Search base DN does not contain user entries | LDAP search error: No such object |
| Attribute mapping mismatch (e.g., uid vs sAMAccountName) | User entry found but username/email empty |
| TLS/SSL trust issues (self‑signed cert, hostname mismatch) | TLS handshake failure or certificate verify failed |
| Malformed group filter or missing memberOf/uniqueMember support | Group lookup failed or empty group list |
Ordered checks
-
Verify network reachability
From the Forgejo host, test TCP connectivity to the LDAP server.
# Replace placeholders with actual values nc -zv <ldap-host> <ldap-port>Required permission: ability to run network utilities (usually any user). Expected check: "Connection to <ldap-host> <ldap-port> port [tcp/*] succeeded!". Risk: none.
-
Test LDAP bind with correct credentials
Use
ldapsearchto confirm the bind DN and password work.ldapsearch -x -H ldap://<ldap-host>:<ldap-port> \ -D '<bind-dn>' -w '<bind-password>' -b '<search-base>' \ '(objectClass=*)' dnRequired permission: read access to the LDAP directory (as defined by bind DN). Expected check: returns at least one entry without error. Risk: exposing the password in shell history; mitigate by using a temporary file or environment variable.
-
Confirm user entry exists under the search base
Search for a specific user using the attribute Forgejo expects for login (e.g., uid or sAMAccountName).
ldapsearch -x -H ldap://<ldap-host>:<ldap-port> \ -D '<bind-dn>' -w '<bind-password>' -b '<search-base>' \ '(<login-attribute>=<username>)' dnReplace <login-attribute> with the attribute configured in Forgejo (uid, sAMAccountName, etc.). Expected check: returns the user’s DN. Risk: none.
-
Validate attribute mapping
Ensure the Forgejo LDAP configuration maps the correct LDAP attributes to username, email, and full name.
Check
app.ini(or environment variables/Docker secrets) for sections like:[auth.ldap] ENABLED = true HOST = <ldap-host> PORT = <ldap-port> USE_SSL = false START_TLS = false BIND_DN = <bind-dn> BIND_PASSWORD = ${LDAP_BIND_PASSWORD} BASE_DN = <search-base> FILTER = (<login-attribute>=%s) USERNAME_ATTRIBUTE = <login-attribute> EMAIL_ATTRIBUTE = mail FIRST_NAME_ATTRIBUTE = givenName LAST_NAME_ATTRIBUTE = snVerify that the values match the directory schema. Expected check: after a test login, Forgejo logs show the retrieved attributes. Risk: mis‑mapping can create duplicate accounts.
-
Test TLS/SSL trust (if using LDAPS or STARTTLS)
Check that the Forgejo host trusts the LDAP server’s certificate. Add SNI handling if the LDAPS server expects it.
openssl s_client -connect <ldap-host>:<ldap-port> -showcerts -servername <ldap-host>Look for "Verify return code: 0 (ok)". If the certificate is self‑signed, add the CA to the system trust store or set
SSL_CERT_FILEin the Forgejo environment. Required permission: ability to run openssl and read certificate files. Risk: none. -
Verify group filter / memberOf configuration
If groups are used for authorization, test the group lookup. Directories without the memberOf overlay can use a
uniqueMemberfilter instead.ldapsearch -x -H ldap://<ldap-host>:<ldap-port> \ -D '<bind-dn>' -w '<bind-password>' -b '<group-base>' \ '(<group-filter>)' dnReplace <group-base> and <group-filter> with the values from Forgejo’s LDAP group settings. Expected check: returns the groups the user belongs to. Risk: none.
Fixes tied to findings
- Network issue: Correct host/IP, port, or firewall rules; ensure the Forgejo host can reach the LDAP server. Also verify outbound SELinux/AppArmor policies (e.g.,
setsebool -P httpd_can_network_connect 1on SELinux systems). - Bad bind credentials: Update
BIND_DNandBIND_PASSWORD(prefer environment variable or Docker secret). Restart Forgejo for the change to take effect. - Wrong search base: Adjust
BASE_DNto an OU that contains the user entries. - Attribute mapping mismatch: Change
USERNAME_ATTRIBUTE,EMAIL_ATTRIBUTE, etc., to match the directory schema. - TLS trust failure: Install the LDAP server’s CA certificate on the Forgejo host, or disable TLS only for testing (not recommended for production). Ensure SNI is supplied if required.
- Group filter error: Correct the
FILTERorGROUP_FILTERsyntax; if the directory lacks memberOf, use a filter that checksuniqueMemberon the group object.
Escalation criteria
If after performing all checks the login still fails:
- Enable debug logging for LDAP in Forgejo (
[log] LEVEL = Debug) and reproduce the failure; examine the detailed trace in the log file (defaultlog/forgejo.logor the path you configured). - Consult the LDAP server logs (requires directory admin access) to see whether the request reached the server and why it was rejected.
- Use a simple bind test tool (e.g.,
ldapwhoami -x -D '<bind-dn>' -w '<bind-password>' -H ldap://<ldap-host>:<ldap-port>) to isolate whether the problem is client‑side or server‑side. - If the issue persists, contact your directory service administrator with the exact bind DN, search base, and filter being used.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.