{"record":{"id":"3acbc0264a54def1","repo":"rancher/rancher","slug":"grant-type-not-supported","errorCode":null,"errorMessage":"grant_type not supported","messagePattern":"grant_type not supported","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"pkg/oidc/provider/token.go","lineNumber":149,"sourceCode":"\t\t\treturn\n\t\t}\n\tcase \"refresh_token\":\n\t\ttokenResponse, oidcErr := h.createRefreshToken(r)\n\t\tif oidcErr != nil {\n\t\t\tlogrus.Debug(\"[OIDC provider] error creating refresh token response: \" + oidcErr.ToString())\n\t\t\toidcErr.Write(http.StatusBadRequest, w)\n\t\t\treturn\n\t\t}\n\t\tw.Header().Set(\"Content-Type\", \"application/json\")\n\t\tw.Header().Set(\"Cache-Control\", \"no-store\")\n\t\tw.Header().Set(\"Pragma\", \"no-cache\")\n\t\terr = json.NewEncoder(w).Encode(tokenResponse)\n\t\tif err != nil {\n\t\t\toidcerror.WriteError(oidcerror.ServerError, \"failed to encode refresh token response\", http.StatusInternalServerError, w)\n\t\t\treturn\n\t\t}\n\tdefault:\n\t\thttp.Error(w, \"grant_type not supported\", http.StatusInternalServerError)\n\t\treturn\n\t}\n}\n\n// createTokenFromCode creates a response with an id_token (if openid scope is\n// provided), access_token and refresh_token\nfunc (h *tokenHandler) createTokenFromCode(r *http.Request) (TokenResponse, *oidcerror.Error) {\n\tcode := r.FormValue(\"code\")\n\tsession, err := h.sessionClient.GetAndRemove(code)\n\tif err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\treturn TokenResponse{}, oidcerror.New(oidcerror.InvalidRequest, \"invalid code\")\n\t\t}\n\t\treturn TokenResponse{}, oidcerror.Newf(oidcerror.ServerError, \"error retrieving session: %s\", err)\n\t}\n\n\t// verify clientID and secret. They can be set in the Authorization header or as a form param as specified in the OIDC spec.\n\tclientID, clientSecret, ok := r.BasicAuth()","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/oidc/provider/token.go#L131-L167","documentation":"The embedded OIDC provider's token endpoint accepts exactly two grant types - authorization_code and refresh_token, matching its advertised grant_types_supported. Any other grant_type (password, client_credentials, device_code, or a typo) hits the default branch and gets a plain-text 500 'grant_type not supported'. RFC 6749 requires 400 with error=unsupported_grant_type, so standards-strict clients may mis-handle the 500 status.","triggerScenarios":"POST to the OIDC token endpoint with grant_type=password, client_credentials, urn:ietf:params:oauth:grant-type:device_code, or a misspelled value; an OIDC client library configured for a flow Rancher does not implement.","commonSituations":"Scripting authentication with password grant instead of the authorization-code flow; service-to-service consumers expecting client-credentials; SDK defaults selecting an unsupported flow.","solutions":["Switch the client to the authorization_code flow (or refresh_token when refreshing).","For machine-to-machine access, use a Rancher API token (Bearer key) instead of the OIDC provider.","Server-side hardening: return 400 with error=unsupported_grant_type per RFC 6749 instead of 500."],"exampleFix":"# before\ncurl -s https://rancher/oidc/token -d grant_type=client_credentials\n# 500 grant_type not supported\n\n# after\ncurl -s https://rancher/oidc/token -d grant_type=authorization_code -d code=... -d redirect_uri=...\n# or use a Rancher API token for machine access","handlingStrategy":"validation","validationCode":"GRANT=authorization_code; [ \"$GRANT\" = authorization_code ] || [ \"$GRANT\" = refresh_token ] || { echo \"unsupported grant_type: $GRANT\"; exit 2; }; curl -s https://rancher/oidc/token -d grant_type=$GRANT ...","typeGuard":"func isSupportedGrantType(g string) bool {\n\treturn g == \"authorization_code\" || g == \"refresh_token\"\n}","tryCatchPattern":"if !isSupportedGrantType(r.Form.Get(\"grant_type\")) { return 400 unsupported_grant_type before hitting the endpoint } - clients should fail fast on configuration, never retry a 500 for this cause.","preventionTips":["Check the provider's advertised grant_types_supported from its discovery document during client config.","Use the authorization-code flow for users and Rancher API tokens for machine access; do not attempt password or client-credentials grants."],"tags":["oidc","oauth","grant-type","token-endpoint"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}