siyuan-note/siyuan · error

discover OAuth authorization server: %w

Error message

discover OAuth authorization server: %w

What it means

Returned by mcpOAuthHandler.Authorize when auth.GetAuthServerMetadata fails for the first authorization server advertised by the protected-resource metadata (prm.AuthorizationServers[0]). This is the step that fetches RFC 8414 metadata (issuer, token endpoint, grant types, etc.). The wrapped error (network, HTTP, JSON-decode) is preserved.

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 251596fc0d)

Solutions

  1. From the kernel host, fetch the metadata URL directly (curl -i) and confirm it returns valid RFC 8414 JSON with an 'issuer' field.
  2. Ensure the kernel host can resolve and reach the auth server; adjust HTTP_PROXY/HTTPS_PROXY and trust the TLS CA.
  3. Verify prm.AuthorizationServers[0] is the correct issuer URL; a misconfigured resource server may advertise the wrong auth server.
  4. If the auth server is down, retry later; this is a transient dependency failure.
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight reachability check to the auth server metadata URL.
func probeAuthServer(ctx context.Context, issuer string) error {
    // HTTP GET issuer + /.well-known/oauth-authorization-server (or as advertised)
    return nil
}

Try / catch

// Retry on transient network errors; surface TLS/DNS issues separately.
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
    // backoff and retry discovery
}

Prevention

When it happens

Trigger: discoverProtectedResource succeeded and produced at least one AuthorizationServers URL, but auth.GetAuthServerMetadata could not GET/parse that URL's metadata document within ctx — DNS failure, connection refused, TLS error, 404, or invalid JSON.

Common situations: Authorization server is on a private network unreachable from the kernel host; metadata endpoint path is wrong (returns HTML/404); TLS cert is untrusted or self-signed; corporate proxy blocks the metadata URL; auth server is temporarily down.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/2a16186cbe5f64e7. Report an issue: GitHub.