{"record":{"id":"dab1435115f190cf","repo":"goharbor/harbor","slug":"entity-not-found","errorCode":null,"errorMessage":"entity not found","messagePattern":"entity not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/ldap/ldap.go","lineNumber":36,"sourceCode":"\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\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\")","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/ldap/ldap.go#L18-L54","documentation":"Sentinel error in Harbor's LDAP package, returned by Session.SearchGroupByDN when the LDAP/AD server answers LDAPResultNoSuchObject — the group DN being used as the search base does not exist in the directory. It flows out of group search (Harbor API POST /api/v2.0/ldap/groups/search with a group DN) and during LDAP group sync when resolving a user's memberOf DNs.","triggerScenarios":"Calling SearchGroupByDN (directly or via the groups-search API / group sync) with a DN that has been deleted, or when ldap_group_base_dn points at a nonexistent subtree so the server returns 'No Such Object' for the base.","commonSituations":"Groups deleted/renamed in Active Directory while users still carry the stale DN in memberOf; typos in ldap_group_base_dn; cross-domain/forest setups where memberOf references DNs from a domain Harbor's configured base cannot see.","solutions":["Verify the group base DN and the failing group DN with an external tool: ldapsearch -H ldap://host -b '<dn>' -s base '(objectclass=*)'.","Correct ldap_group_base_dn in the configuration if it points to a nonexistent subtree.","Treat ErrNotFound as skip-able during sync (group no longer exists) rather than fatal — filter stale DNs before calling SearchGroupByDN."],"exampleFix":"// Go: before\ngroups, err := session.SearchGroupByDN(dn)\nif err != nil { return err }\n// after\ngroups, err := session.SearchGroupByDN(dn)\nif errors.Is(err, ldap.ErrNotFound) {\n    log.Warnf(\"group %s no longer exists in LDAP, skipping\", dn)\n    return nil\n}\nif err != nil { return err }","handlingStrategy":"try-catch","validationCode":"// Go: cheap pre-checks before SearchGroupByDN\nif _, err := goldap.ParseDN(groupDN); err != nil { /* bad DN — fix data */ }\n// Optionally verify the DN exists with a base-scope search before relying on it","typeGuard":"// Go\nimport \"errors\"\nimport harborldap \"github.com/goharbor/harbor/src/pkg/ldap\"\n\nfunc isGroupNotFound(err error) bool {\n    return errors.Is(err, harborldap.ErrNotFound)\n}","tryCatchPattern":"groups, err := session.SearchGroupByDN(dn)\nif err != nil {\n    if errors.Is(err, ldap.ErrNotFound) {\n        // group DN no longer exists in the directory: skip it (stale memberOf), don't fail the sync\n        continue\n    }\n    return err\n}","preventionTips":["Treat ErrNotFound as skip-able during group sync — AD often leaves stale memberOf DNs.","Validate ldap_group_base_dn with ldapsearch right after any directory restructuring.","Log offending DNs so directory cleanup of deleted groups is actionable."],"tags":["ldap","group-sync","active-directory","harbor"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}