{"record":{"id":"d332eef4c67a8fe3","repo":"rancher/rancher","slug":"invalid-endpoint-v-d332ee","errorCode":null,"errorMessage":"invalid endpoint %v","messagePattern":"invalid endpoint (.+?)","errorType":"http","errorClass":null,"httpStatus":404,"severity":"error","filePath":"pkg/api/norman/customization/gke/handler.go","lineNumber":183,"sourceCode":"\t\t}\n\n\t\tshowDeprecated := strings.ToLower(req.URL.Query().Get(\"showDeprecated\")) == \"true\"\n\n\t\tif serialized, errCode, err = listImageFamilyForProject(req.Context(), capa, imageProject, imageFamily, showDeprecated); err != nil {\n\t\t\tlogrus.Errorf(\"[gke-handler] error getting images from image family: %v\", err)\n\t\t\thandleErr(writer, errCode, err)\n\t\t\treturn\n\t\t}\n\t\twriter.Write(serialized)\n\tcase \"gkeDiskTypes\":\n\t\tif serialized, errCode, err = listDiskTypes(req.Context(), capa); err != nil {\n\t\t\tlogrus.Errorf(\"[gke-handler] error getting disk types: %v\", err)\n\t\t\thandleErr(writer, errCode, err)\n\t\t\treturn\n\t\t}\n\t\twriter.Write(serialized)\n\tdefault:\n\t\thandleErr(writer, httperror.NotFound.Status, fmt.Errorf(\"invalid endpoint %v\", resourceType))\n\t}\n}\n\nfunc (h *handler) getCloudCredential(req *http.Request, cap *Capabilities, credID string, projectIDRequired bool) (int, error) {\n\tns, name := ref.Parse(credID)\n\tif ns == \"\" || name == \"\" {\n\t\tlogrus.Errorf(\"[GKE] invalid cloud credential ID %s\", credID)\n\t\treturn http.StatusBadRequest, fmt.Errorf(\"invalid cloud credential ID %s\", credID)\n\t}\n\n\tvar accessCred client.CloudCredential // var to check access\n\tif err := access.ByID(h.generateAPIContext(req), &schema.Version, client.CloudCredentialType, credID, &accessCred); err != nil {\n\t\tapiError, ok := err.(*httperror.APIError)\n\t\tif !ok {\n\t\t\treturn httperror.NotFound.Status, err\n\t\t}\n\t\tif apiError.Code.Status == httperror.NotFound.Status {\n\t\t\treturn httperror.InvalidBodyContent.Status, fmt.Errorf(\"cloud credential not found\")","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/api/norman/customization/gke/handler.go#L165-L201","documentation":"Returned by the default branch of the GKE handler's switch over resourceType: none of the known sub-endpoint names matched, so the handler responds with HTTP 404 ('invalid endpoint <resourceType>'). It means the router itself was reached but the requested sub-resource name is not one of the supported cases (gkeMachineTypes, gkeNetworks, gkeSubnetworks, gkeServiceAccounts, gkeVersions, gkeSharedSubnets, gkeFamiliesFromProject, gkeImageFamilies, gkeDiskTypes).","triggerScenarios":"resourceType misspelled or wrong case, e.g. gkeMachineType (singular) or GKE disk types; requesting a sub-endpoint that exists only in a newer/older Rancher version than the one serving the request.","commonSituations":"Dashboard/backend version skew after partial upgrade; typos in custom scripts; renamed endpoints across Rancher releases; clients hardcoding a resource list that drifts from the server.","solutions":["Correct the resourceType value to one of the supported case-sensitive names (gkeMachineTypes, gkeNetworks, gkeSubnetworks, gkeServiceAccounts, gkeVersions, gkeSharedSubnets, gkeFamiliesFromProject, gkeImageFamilies, gkeDiskTypes)","If the name looks right, check exact casing and no trailing whitespace/encoding artifacts","On version skew, align the client (dashboard/extension) version with the Rancher server version"],"exampleFix":"// before\nGET /v3/gke/endpoints?resourceType=gkeDiskType&cloudCredentialId=...\n// after\nGET /v3/gke/endpoints?resourceType=gkeDiskTypes&cloudCredentialId=...","handlingStrategy":"type-guard","validationCode":"const VALID_RESOURCE_TYPES = new Set([\n  'gkeMachineTypes', 'gkeNetworks', 'gkeSubnetworks', 'gkeServiceAccounts',\n  'gkeVersions', 'gkeSharedSubnets', 'gkeFamiliesFromProject', 'gkeImageFamilies', 'gkeDiskTypes'\n]);\nif (!VALID_RESOURCE_TYPES.has(resourceType)) {\n  throw new Error(`unsupported resourceType '${resourceType}'; valid: ${[...VALID_RESOURCE_TYPES].join(', ')}`);\n}","typeGuard":"const isGkeResourceType = (v) => typeof v === 'string' && new Set(['gkeMachineTypes','gkeNetworks','gkeSubnetworks','gkeServiceAccounts','gkeVersions','gkeSharedSubnets','gkeFamiliesFromProject','gkeImageFamilies','gkeDiskTypes']).has(v);","tryCatchPattern":"try { const res = await fetch(url); if (res.status === 404) { checkResourceTypeSpelling(resourceType); } } catch (e) { reportNetwork(e); }","preventionTips":["Centralize the resourceType union in one typed constant shared by all call sites","Pin dashboard/extension versions to the Rancher server version to avoid endpoint drift","Treat 'invalid endpoint' as a programmer error: log loudly, do not retry"],"tags":["gke","routing","http-404","rancher","version-skew"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}