goharbor/harbor · warning · ErrDuplicateLDAPGroup
a LDAP user group with same DN already exist
Error message
a LDAP user group with same DN already exist
What it means
Sentinel ErrDuplicateLDAPGroup is returned by the LDAP auth helper (src/core/auth/ldap/ldap.go:319) when creating or updating a user group whose DN is already owned by another LDAP user group in Harbor's database. DNs must be unique per group.
Source
Thrown at src/core/auth/authenticator.go:44
libErrors "github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/user"
"github.com/goharbor/harbor/src/pkg/usergroup/model"
)
// 1.5 seconds
const frozenTime time.Duration = 1500 * time.Millisecond
var lock = NewUserLock(frozenTime)
// ErrorUserNotExist ...
var ErrorUserNotExist = errors.New("user does not exist")
// ErrorGroupNotExist ...
var ErrorGroupNotExist = errors.New("group does not exist")
// ErrDuplicateLDAPGroup ...
var ErrDuplicateLDAPGroup = errors.New("a LDAP user group with same DN already exist")
// ErrInvalidLDAPGroupDN ...
var ErrInvalidLDAPGroupDN = errors.New("the LDAP group DN is invalid")
// ErrNotSupported ...
var ErrNotSupported = errors.New("not supported")
// ErrAuth is the type of error to indicate a failed authentication due to user's error.
type ErrAuth struct {
details string
}
// Error ...
func (ea ErrAuth) Error() string {
return fmt.Sprintf("Failed to authenticate user, due to error '%s'", ea.details)
}
// NewErrAuth ...View on GitHub (pinned to 7b2fd08cc5)
Solutions
- List existing groups (GET /api/v2.0/usergroups) and update the existing one instead of creating a new one
- If the old entry is stale (group gone from the directory), delete it first
- Give the new group its correct, distinct DN
Example fix
// before: creating a group with a DN that already exists
$ curl -u admin:Pass -X POST https://harbor.example.com/api/v2.0/usergroups \
-H 'Content-Type: application/json' \
-d '{"group_name":"devs","group_type":1,"ldap_group_dn":"cn=devs,ou=groups,dc=example,dc=com"}'
// after: reuse the existing group (lookup then PUT)
$ curl -u admin:Pass 'https://harbor.example.com/api/v2.0/usergroups?groupname=devs'
$ curl -u admin:Pass -X PUT https://harbor.example.com/api/v2.0/usergroups/7 \
-d '{"group_name":"devs","group_type":1,"ldap_group_dn":"cn=dev-team,ou=groups,dc=example,dc=com"}' Defensive patterns
Strategy: try-catch
Validate before calling
// Before creating, ensure no group owns the DN yet
groups, _, _ := client.UsergroupsApi.ListUserGroups(ctx).Execute()
for _, g := range groups {
if g.LdapGroupDn != nil && *g.LdapGroupDn == dn { return errors.New("DN already in use") }
} Type guard
func isDuplicateLDAPGroup(err error) bool { return errors.Is(err, auth.ErrDuplicateLDAPGroup) } Try / catch
err := ldap.CreateUserGroup(...)
if errors.Is(err, auth.ErrDuplicateLDAPGroup) {
// switch to updating the existing group instead of failing
} Prevention
- Make create-or-update idempotent keyed on DN
- Clean stale user groups after directory renames
When it happens
Trigger: POST /api/v2.0/usergroups with a DN that already exists on another group; PUT /api/v2.0/usergroups/{id} changing a group's DN to one already in use.
Common situations: Recreating a group that still exists in Harbor after it was renamed in the directory duplicate entries left behind by LDAP migrations or manual inserts.
Related errors
- group does not exist
- the LDAP group DN is invalid
- should provide a group name
- BAD_REQUEST
- entity not found
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/0b1e23465cbe0101.
Report an issue: GitHub.