siyuan-note/siyuan · error
OAuth authorization failed
Error message
OAuth authorization failed: %s
What it means
The OAuth redirect back to the local callback endpoint may carry an error parameter (per RFC 6749 section 4.1.2.1, e.g. access_denied, invalid_scope). When the browser callback reports such an error, the flow surfaces it verbatim as 'OAuth authorization failed: <server error>'.
Solutions
- Read the error text after the colon to identify the IdP's reason (e.g. access_denied, invalid_scope)
- Retry and approve the consent request in the browser
- If invalid_scope, align the server's advertised scopes with what the client requests, or grant the client those scopes
- If the IdP rejects PKCE or the resource parameter, update/fix the authorization server configuration
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check that requested scopes are within what the resource metadata advertises
for _, s := range requestedScopes {
if !slices.Contains(prm.ScopesSupported, s) { /* scope will likely be denied */ }
} Try / catch
if err := h.Authorize(ctx, true); err != nil {
if strings.HasPrefix(err.Error(), "OAuth authorization failed:") {
idpErr := strings.TrimPrefix(err.Error(), "OAuth authorization failed: ")
// branch on access_denied / invalid_scope etc.
}
} Prevention
- Instruct users to approve the consent screen rather than cancel it
- Ensure requested scopes match the server's supported scopes
- Verify the client is allowed the requested scopes in the IdP's client configuration
When it happens
Trigger: User completes the authorization redirect but the IdP redirected to the callback with error=... (plus optional error_description), e.g. after the user denied consent or the request was rejected (invalid_scope, access_denied, server_error).
Common situations: User clicked 'Deny'/'Cancel' on the consent screen; the requested scopes are not grantable for this client; the IdP rejected PKCE or the resource parameter; account restrictions on the chosen user.
Related errors
- configuration is not initialized
- discover OAuth authorization server
- exchange OAuth authorization code
- mcp oauth authorization required
- OAuth authorization server does not support a compatible…
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/6cbecec05d12ff6d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/mcp/client/oauth.go:386
}
oauthFlows.Lock()
oauthFlows.items[flowID] = flow
oauthFlows.Unlock()
defer removeOAuthFlow(flowID, flow)
setMCPRuntimeStateForContext(ctx, h.server.ID, "authorizing", 0, "", authorizationURL)
var callback oauthCallbackResult
timer := time.NewTimer(oauthAuthorizationTimeout)
defer timer.Stop()
select {
case callback = <-flow.Result:
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
return fmt.Errorf("OAuth authorization timed out")
}
if callback.Error != "" {
return fmt.Errorf("OAuth authorization failed: %s", callback.Error)
}
if callback.State != state {
return fmt.Errorf("OAuth state mismatch")
}
if callback.Code == "" {
return fmt.Errorf("OAuth callback did not include an authorization code")
}
exchangeCtx := context.WithValue(ctx, oauth2.HTTPClient, h.client)
token, err := config.Exchange(exchangeCtx, callback.Code,
oauth2.VerifierOption(verifier),
oauth2.SetAuthURLParam("resource", prm.Resource))
if err != nil {
return fmt.Errorf("exchange OAuth authorization code: %w", err)
}
if token.TokenType != "" && !strings.EqualFold(token.TokenType, "Bearer") {
return fmt.Errorf("OAuth token endpoint returned unsupported token type %q", token.TokenType)
}View on GitHub (pinned to 9f775e8a12)