goharbor/harbor · error
empty password
Error message
empty password
What it means
Sentinel error returned by the LDAP controller's Ping (backing POST /api/v2.0/ldap/ping) when no search password is available: the request carried no password and the stored ldap_search_password resolves to empty, or the current auth mode is not db_auth… specifically not LDAP, so there is no stored password to reuse. ldap_search_password is write-only, so GET configurations returning empty never proves it is set.
Source
Thrown at src/pkg/ldap/ldap.go:39
"net"
"net/url"
"strings"
"time"
goldap "github.com/go-ldap/ldap/v3"
"github.com/goharbor/harbor/src/lib/config/models"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/ldap/model"
)
const pageSize = 1000
// ErrNotFound ...
var ErrNotFound = errors.New("entity not found")
// ErrEmptyPassword ...
var ErrEmptyPassword = errors.New("empty password")
// ErrInvalidCredential ...
var ErrInvalidCredential = errors.New("invalid credential")
// ErrLDAPServerTimeout ...
var ErrLDAPServerTimeout = errors.New("ldap server network timeout")
// ErrLDAPPingFail ...
var ErrLDAPPingFail = errors.New("fail to ping LDAP server")
// ErrDNSyntax ...
var ErrDNSyntax = errors.New("invalid DN syntax")
// ErrInvalidFilter ...
var ErrInvalidFilter = errors.New("invalid filter syntax")
// ErrEmptyBaseDN ...
var ErrEmptyBaseDN = errors.New("empty base dn")View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Send the search password in the ping request body so no stored secret is needed.
- Or save it first: PUT /api/v2.0/configurations with ldap_search_password, then ping without it.
- Switch auth_mode to ldap_auth before pinging if you expect to reuse the stored secret.
Example fix
# before
curl -X POST https://harbor/api/v2.0/ldap/ping -d '{"url": "ldaps://ad.example.com:636"}'
# after
curl -X POST https://harbor/api/v2.0/ldap/ping -d '{"url": "ldaps://ad.example.com:636", "search_dn": "cn=svc-harbor,ou=svc,dc=example,dc=com", "search_password": "<secret>"}' Defensive patterns
Strategy: validation
Validate before calling
// Before POST /api/v2.0/ldap/ping with no password:
// ensure a stored secret exists AND auth mode is ldap, else include the password in the request
if req.searchPassword == "" {
if authMode != "ldap_auth" || !ldapSearchPasswordIsConfigured {
fail("include search_password in the ping request")
}
} Type guard
func isLdapEmptyPassword(err error) bool { return errors.Is(err, ldap.ErrEmptyPassword) } Try / catch
After calling ping, if errors.Is(err, ldap.ErrEmptyPassword) → prompt for the bind password or save ldap_search_password first, then retry the ping with credentials inline.
Prevention
- Always pass search_dn + search_password explicitly in ping requests during initial setup.
- Note GET /api/v2.0/configurations never returns the password — do not use its absence as proof.
- Set auth_mode to ldap_auth before passwordless pings.
When it happens
Trigger: POST /api/v2.0/ldap/ping with an empty/omitted password while (a) ldap_search_password was never saved, or (b) auth_mode is db_auth/oidc/uaa so no LDAP secret exists; internally via controller.Ping → defaultPassword.
Common situations: Fresh Harbor installs testing LDAP before saving the bind password; deployments where the password was configured via harbor.yml LDAP_PASSWORD but env-based migration dropped it; testing LDAP while auth mode is still db_auth.
Related errors
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/1e636b5984f9009b.
Report an issue: GitHub.