{"record":{"id":"9242aa35baca26a5","repo":"siyuan-note/siyuan","slug":"oauth-authorization-server-does-not-support-dynami","errorCode":null,"errorMessage":"OAuth authorization server does not support dynamic client registration","messagePattern":"OAuth authorization server does not support dynamic client registration","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/client/oauth.go","lineNumber":287,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\tcallbackURL := fmt.Sprintf(\"http://127.0.0.1:%s/api/ai/mcp/oauth/callback/%s\", util.ServerPort, flowID)\n\tscopes := append([]string(nil), prm.ScopesSupported...)\n\tif len(scopes) == 0 {\n\t\tscopes = append(scopes, asm.ScopesSupported...)\n\t}\n\tfor _, scope := range strings.Fields(bearerChallengeParam(challenges, \"scope\")) {\n\t\tif !slices.Contains(scopes, scope) {\n\t\t\tscopes = append(scopes, scope)\n\t\t}\n\t}\n\tregistrationCredential := credential\n\tcanReuseRegistration := hasCredential && credential.Issuer == asm.Issuer && credential.RedirectURL == callbackURL &&\n\t\tcredential.ClientID != \"\" && !oauthClientRegistrationExpired(credential) && oauthScopesContain(credential.Scopes, scopes)\n\tif !canReuseRegistration {\n\t\tif asm.RegistrationEndpoint == \"\" {\n\t\t\treturn fmt.Errorf(\"OAuth authorization server does not support dynamic client registration\")\n\t\t}\n\t\ttokenAuthMethod := preferredTokenAuthMethod(asm.TokenEndpointAuthMethodsSupported)\n\t\tif len(asm.TokenEndpointAuthMethodsSupported) > 0 && tokenAuthMethod == \"\" {\n\t\t\treturn fmt.Errorf(\"OAuth authorization server does not support a compatible token endpoint authentication method\")\n\t\t}\n\t\tgrantTypes := []string{\"authorization_code\"}\n\t\tif len(asm.GrantTypesSupported) == 0 || slices.Contains(asm.GrantTypesSupported, \"refresh_token\") {\n\t\t\tgrantTypes = append(grantTypes, \"refresh_token\")\n\t\t}\n\t\tregistration, registerErr := oauthex.RegisterClient(ctx, asm.RegistrationEndpoint, &oauthex.ClientRegistrationMetadata{\n\t\t\tRedirectURIs:            []string{callbackURL},\n\t\t\tTokenEndpointAuthMethod: tokenAuthMethod,\n\t\t\tGrantTypes:              grantTypes,\n\t\t\tResponseTypes:           []string{\"code\"},\n\t\t\tClientName:              \"SiYuan\",\n\t\t\tScope:                   strings.Join(scopes, \" \"),\n\t\t\tApplicationType:         \"native\",\n\t\t}, h.client)","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/client/oauth.go#L269-L305","documentation":"Thrown at oauth.go:286-287 when a fresh client registration is required (no reusable registration exists) but the AS metadata has no registration_endpoint. SiYuan performs RFC 7591 dynamic client registration because the redirect URI is a per-run localhost callback; without a registration endpoint it cannot obtain a client_id.","triggerScenarios":"First-time (or post-expiry) interactive Authorize where canReuseRegistration is false AND asm.RegistrationEndpoint == ''. Reuse fails when issuer changed, redirect URL changed, client_id empty, registration expired, or scopes no longer covered.","commonSituations":"AS that requires pre-registered clients (no RFC 7591 support); corporate AS where DCR is disabled by policy; AS upgraded and dropped DCR; the stored credential was invalidated (e.g. secret expired) forcing re-registration.","solutions":["Enable RFC 7591 dynamic client registration on the AS and publish registration_endpoint in its metadata.","If DCR is unavailable, use an AS that supports it, since SiYuan's localhost-callback model depends on per-run registration.","If registration was only rejected because scopes changed, confirm the AS exposes the needed scopes in scopes_supported so the next attempt can reuse a registration."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"asm, err := auth.GetAuthServerMetadata(ctx, issuerURL, http.DefaultClient)\nif err != nil { return err }\nif asm.RegistrationEndpoint == \"\" {\n    return fmt.Errorf(\"AS %s does not support RFC 7591 dynamic client registration; required by SiYuan\", issuerURL)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Confirm registration_endpoint is advertised before first authorization.","Keep stored registrations valid (matching issuer, redirect URL, scopes) to maximize reuse and avoid re-registration."],"tags":["oauth","mcp","dynamic-client-registration","rfc7591","metadata"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}