{"record":{"id":"b2ce9db4355a9168","repo":"goharbor/harbor","slug":"should-provide-a-group-name","errorCode":null,"errorMessage":"should provide a group name","messagePattern":"should provide a group name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/core/auth/authproxy/auth.go","lineNumber":197,"sourceCode":"\tif err != nil {\n\t\tlog.Warningf(\"Failed to refresh configuration for HTTP Auth Proxy Authenticator, error: %v, the default settings will be used\", err)\n\t}\n\tvar ug *model.UserGroup\n\tif a.SkipSearch {\n\t\tug = &model.UserGroup{\n\t\t\tGroupName: groupKey,\n\t\t\tGroupType: common.HTTPGroupType,\n\t\t}\n\t\treturn ug, nil\n\t}\n\treturn nil, nil\n}\n\n// OnBoardGroup create user group entity in Harbor DB, altGroupName is not used.\nfunc (a *Auth) OnBoardGroup(ctx context.Context, u *model.UserGroup, _ string) error {\n\t// if group name provided, on board the user group\n\tif len(u.GroupName) == 0 {\n\t\treturn errors.New(\"should provide a group name\")\n\t}\n\tu.GroupType = common.HTTPGroupType\n\terr := usergroup.Ctl.Ensure(ctx, u)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (a *Auth) fillInModel(u *models.User) error {\n\tif strings.TrimSpace(u.Username) == \"\" {\n\t\treturn fmt.Errorf(\"username cannot be empty\")\n\t}\n\tu.Realname = u.Username\n\tu.Password = \"1234567ab\"\n\tu.Comment = userEntryComment\n\tif strings.Contains(u.Username, \"@\") {\n\t\tu.Email = u.Username","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/core/auth/authproxy/auth.go#L179-L215","documentation":"Auth-proxy OnBoardGroup rejects a model.UserGroup whose GroupName is empty before touching the database. It means a group association was detected for the HTTP-authenticated user, but the group name Harbor derived (from the configured group header) is blank, so there is nothing to onboard.","triggerScenarios":"Login via auth proxy where the group header is present but its value is empty (e.g. 'X-Remote-Group:'), or the derived group list contains an empty element.","commonSituations":"Reverse proxy strips the header value for certain users group header name misconfigured so an empty value leaks through upstream identity provider returns an empty group entry.","solutions":["Verify the group header (e.g. X-Remote-Group) sends a non-empty value for this user","Fix the reverse proxy / IdP to emit the real group name","If the user has no group, omit the header entirely - empty values are rejected, not skipped"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// On the proxy side, never forward an empty group header\ng := strings.TrimSpace(r.Header.Get(\"X-Remote-Group\"))\nif g == \"\" {\n    r.Header.Del(\"X-Remote-Group\") // absent instead of empty\n}","typeGuard":"func isEmptyGroupErr(err error) bool { return err != nil && strings.Contains(err.Error(), \"should provide a group name\") }","tryCatchPattern":"if err := auth.OnBoardGroup(ctx, ug, \"\"); err != nil {\n    if strings.Contains(err.Error(), \"should provide a group name\") {\n        // upstream header empty: alert IdP/proxy config, do not retry\n    }\n}","preventionTips":["Filter empty group values at the reverse proxy","Alert on any login where a group is present but unnamed","Keep auth proxy header contract documented with the IdP team"],"tags":["harbor","auth-proxy","usergroup","validation"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}