siyuan-note/siyuan · error
discover OAuth authorization server
Error message
discover OAuth authorization server: %w
What it means
Wraps a failure from auth.GetAuthServerMetadata, which fetches the authorization server's RFC 8414 metadata (/.well-known/oauth-authorization-server) for the first authorization server advertised by the protected resource. The library throws this so callers can tell metadata discovery failures apart from later token/registration failures.
Solutions
- Open https://<auth-server>/.well-known/oauth-authorization-server (and /.well-known/openid-configuration) in a browser to confirm metadata is served
- Fix the authorization_servers entry in the resource metadata so it points at the real IdP issuer URL
- Check network/proxy/VPN connectivity to the authorization server from the SiYuan host
- Inspect the wrapped %w error in the message to identify transport vs parse failure and fix accordingly
Defensive patterns
Strategy: try-catch
Validate before calling
meta, err := auth.GetAuthServerMetadata(ctx, authServerURL, http.DefaultClient)
if err != nil {
return fmt.Errorf("pre-flight discovery failed: %w", err)
} Try / catch
if err := h.Authorize(ctx, req, resp); err != nil {
var discErr *fmt.Errorf // match on wrapped discovery error text
if strings.Contains(err.Error(), "discover OAuth authorization server:") {
retryLater(err)
}
} Prevention
- Pre-flight check /.well-known/oauth-authorization-server reachability when adding an MCP server
- Verify authorization_servers entries in the resource metadata resolve to live issuer URLs
- Ensure firewalls/VPNs/proxies allow outbound HTTPS to the IdP from the SiYuan host
When it happens
Trigger: Authorize reached the discovery step but GetAuthServerMetadata returned an error: the authorization-server URL is unreachable, DNS fails, TLS fails, the well-known endpoint 404s, or the response is not valid metadata JSON.
Common situations: Authorization server behind a firewall/VPN not currently connected; issuer URL typo in the resource metadata; well-known endpoints not deployed on the IdP; corporate proxy blocking the request; IdP down.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- OAuth protected resource metadata not found
- validate OAuth issuer
- validate OAuth protected resource
- OAuth authorization server metadata not found
- OAuth protected resource metadata has no authorization…
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/2a16186cbe5f64e7.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/mcp/client/oauth.go:214
return fmt.Errorf("server returned %s", resp.Status)
}
interactive := h.interactive.Load()
if interactive {
defer func() {
if retErr != nil && !errors.Is(retErr, context.Canceled) {
setMCPRuntimeStateForContext(ctx, h.server.ID, "authorization_required", 0, retErr.Error(), "")
}
}()
}
prm, err := discoverProtectedResource(ctx, challenges, req.URL.String(), h.client)
if err != nil {
return err
}
asm, err := auth.GetAuthServerMetadata(ctx, prm.AuthorizationServers[0], h.client)
if err != nil {
return fmt.Errorf("discover OAuth authorization server: %w", err)
}
if asm == nil {
return fmt.Errorf("OAuth authorization server metadata not found")
}
credential, hasCredential := getOAuthCredential(h.server.ID, h.server.URL)
if hasCredential && credential.Issuer == asm.Issuer {
credential.TokenEndpoint = asm.TokenEndpoint
credential.RevocationEndpoint = asm.RevocationEndpoint
}
if hasCredential && credential.Issuer == asm.Issuer && credential.RefreshToken != "" &&
challengeError != "insufficient_scope" && !credential.Rejected && !oauthClientRegistrationExpired(credential) {
refreshed, permanent, refreshErr := refreshOAuthCredential(ctx, h.client, credential)
if refreshErr == nil {
if saveErr := putOAuthCredential(refreshed); saveErr != nil {
logging.LogWarnf("mcp oauth: save refreshed credentials failed: %s", saveErr)
}
h.sourceMu.Lock()
h.source = &storedOAuthTokenSource{credential: refreshed, client: h.client}View on GitHub (pinned to 9f775e8a12)