{"record":{"id":"6df3588925131c30","repo":"rancher/rancher","slug":"invalid-hostname-provided","errorCode":null,"errorMessage":"invalid hostname provided","messagePattern":"invalid hostname provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/auth/providers/googleoauth/goauth_helper.go","lineNumber":29,"sourceCode":"\tapiv3 \"github.com/rancher/rancher/pkg/apis/management.cattle.io/v3\"\n\t\"github.com/sirupsen/logrus\"\n\t\"golang.org/x/oauth2\"\n\t\"golang.org/x/oauth2/google\"\n\tadmin \"google.golang.org/api/admin/directory/v1\"\n\t\"google.golang.org/api/googleapi\"\n)\n\nfunc (g *googleOauthProvider) getUserInfoAndGroups(adminSvc *admin.Service, gOAuthToken *oauth2.Token, config *apiv3.GoogleOauthConfig, testAndEnableAction bool) (apiv3.Principal, []apiv3.Principal, error) {\n\tvar userPrincipal apiv3.Principal\n\tvar groupPrincipals []apiv3.Principal\n\t// use the access token to make requests, get user info\n\tuser, err := g.goauthClient.getUser(gOAuthToken.AccessToken, config)\n\tif err != nil {\n\t\treturn userPrincipal, groupPrincipals, err\n\t}\n\tif testAndEnableAction {\n\t\tif user.HostedDomain != config.Hostname {\n\t\t\treturn userPrincipal, groupPrincipals, fmt.Errorf(\"invalid hostname provided\")\n\t\t}\n\t}\n\tuserPrincipal = g.toPrincipal(userType, *user, nil)\n\tuserPrincipal.Me = true\n\tlogrus.Debugf(\"[Google OAuth] loginuser: Obtained userinfo using oauth access token\")\n\n\tgroupPrincipals, err = g.getGroupsUserBelongsTo(adminSvc, user.SubjectUniqueID, user.HostedDomain, config)\n\tif err != nil {\n\t\t// The error for this group request could be 403, because svc acc was not provided, and we're relying on individual\n\t\t// users' creds to get groups\n\t\tif config.ServiceAccountCredential == \"\" {\n\t\t\tvar gErr *googleapi.Error\n\t\t\tif !errors.As(err, &gErr) || gErr.Code != http.StatusForbidden {\n\t\t\t\t// if the error is not forbidden, return the error\n\t\t\t\treturn userPrincipal, groupPrincipals, err\n\t\t\t}\n\t\t\t// if the error is forbidden, don't throw any error, just no group principals will be returned\n\t\t} else {","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/auth/providers/googleoauth/goauth_helper.go#L11-L47","documentation":"Thrown during the testAndApply/login flow for Google OAuth when the authenticated user's hd (hosted domain) claim does not equal the hostname configured in the GoogleOauthConfig. It is the provider's guard ensuring only members of the configured Google Workspace domain can enable or log in via this provider. It only fires when testAndEnableAction is true (enabling the provider) or during login enforcement against config.Hostname.","triggerScenarios":"Calling testAndApply while signed in with a @gmail.com personal account while config.Hostname is set to a Workspace domain; hostname configured with a scheme or typo such as 'https://example.com' or 'example.co'; a Workspace user whose hd claim is a secondary/alias domain differing from the configured hostname.","commonSituations":"Admin testing the provider with their personal Google account; trailing whitespace or uppercase in the hostname field; Google account is from a different Workspace domain than intended; copy-pasting the full origin instead of the bare domain.","solutions":["Authenticate with a user account that belongs to the exact configured Workspace domain (user@example.com when Hostname=example.com)","Fix config.Hostname to be the bare domain only, lowercase, no scheme, no trailing slash","If multiple domains are legitimate, ensure the primary domain is configured and users log in with accounts from it"],"exampleFix":"# before (GoogleOauthConfig CR)\nspec:\n  hostname: https://mycompany.com/\n\n# after\nspec:\n  hostname: mycompany.com","handlingStrategy":"validation","validationCode":"// normalizeHostname strips scheme/space and lowercases so the hd comparison matches.\nfunc normalizeHostname(h string) string {\n    h = strings.TrimSpace(strings.ToLower(h))\n    h = strings.TrimPrefix(h, \"https://\")\n    h = strings.TrimPrefix(h, \"http://\")\n    return strings.Trim(h, \"/\")\n}","typeGuard":null,"tryCatchPattern":"if user.HostedDomain != normalizeHostname(config.Hostname) {\n    return fmt.Errorf(\"user domain %q not in configured hostname %q\", user.HostedDomain, config.Hostname)\n}","preventionTips":["Always test-and-enable with an account from the configured Workspace domain","Store hostname as bare lowercase domain, no scheme","Document the single allowed domain for users of this provider"],"tags":["go","google-oauth","hosted-domain","configuration","auth"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}