{"record":{"id":"1e636b5984f9009b","repo":"goharbor/harbor","slug":"empty-password","errorCode":null,"errorMessage":"empty password","messagePattern":"empty password","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/ldap/ldap.go","lineNumber":39,"sourceCode":"\t\"net\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\tgoldap \"github.com/go-ldap/ldap/v3\"\n\n\t\"github.com/goharbor/harbor/src/lib/config/models\"\n\t\"github.com/goharbor/harbor/src/lib/log\"\n\t\"github.com/goharbor/harbor/src/pkg/ldap/model\"\n)\n\nconst pageSize = 1000\n\n// ErrNotFound ...\nvar ErrNotFound = errors.New(\"entity not found\")\n\n// ErrEmptyPassword ...\nvar ErrEmptyPassword = errors.New(\"empty password\")\n\n// ErrInvalidCredential ...\nvar ErrInvalidCredential = errors.New(\"invalid credential\")\n\n// ErrLDAPServerTimeout ...\nvar ErrLDAPServerTimeout = errors.New(\"ldap server network timeout\")\n\n// ErrLDAPPingFail ...\nvar ErrLDAPPingFail = errors.New(\"fail to ping LDAP server\")\n\n// ErrDNSyntax ...\nvar ErrDNSyntax = errors.New(\"invalid DN syntax\")\n\n// ErrInvalidFilter ...\nvar ErrInvalidFilter = errors.New(\"invalid filter syntax\")\n\n// ErrEmptyBaseDN ...\nvar ErrEmptyBaseDN = errors.New(\"empty base dn\")","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/ldap/ldap.go#L21-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ncurl -X POST https://harbor/api/v2.0/ldap/ping -d '{\"url\": \"ldaps://ad.example.com:636\"}'\n# after\ncurl -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>\"}'","handlingStrategy":"validation","validationCode":"// Before POST /api/v2.0/ldap/ping with no password:\n// ensure a stored secret exists AND auth mode is ldap, else include the password in the request\nif req.searchPassword == \"\" {\n    if authMode != \"ldap_auth\" || !ldapSearchPasswordIsConfigured {\n        fail(\"include search_password in the ping request\")\n    }\n}","typeGuard":"func isLdapEmptyPassword(err error) bool { return errors.Is(err, ldap.ErrEmptyPassword) }","tryCatchPattern":"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.","preventionTips":["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."],"tags":["ldap","auth","config","secrets","harbor"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}