siyuan-note/siyuan · error

OAuth authorization server does not support PKCE S256

Error message

OAuth authorization server does not support PKCE S256

What it means

During an interactive authorization the discovered authorization-server metadata's CodeChallengeMethodsSupported does not include S256. SiYuan's MCP client always uses PKCE with S256 (plain is rejected as insecure), so a server lacking S256 cannot complete the flow and the client refuses to start it.

Solutions

  1. Upgrade or reconfigure the authorization server to enable PKCE with the S256 code challenge method
  2. Check IdP settings (e.g. client/policy config) that toggle supported code_challenge_methods
  3. If the IdP genuinely cannot support S256, use a different OAuth provider or a non-OAuth connection method for this MCP server
Defensive patterns

Strategy: validation

Validate before calling

asm, err := auth.GetAuthServerMetadata(ctx, authServerURL, client)
if err == nil && asm != nil && !slices.Contains(asm.CodeChallengeMethodsSupported, "S256") {
    return errors.New("IdP lacks PKCE S256; fix or replace before connecting")
}

Try / catch

if err := h.Authorize(ctx, req, resp); err != nil && strings.Contains(err.Error(), "PKCE S256") {
    showIncompatibleServerDialog(err)
}

Prevention

When it happens

Trigger: Interactive Authorize (user-triggered) reaches the capability checks after metadata discovery, and asm.CodeChallengeMethodsSupported omits "S256" (or is empty/absent for plain-PKCE-only or pre-PKCE servers).

Common situations: Legacy OAuth server or old IdP version predating PKCE support; IdP configured with PKCE disabled; homemade OAuth implementation that only supports plain or no PKCE.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/347f0d1194fbe4d4. Report an issue: GitHub.

Appendix: source

Thrown at kernel/mcp/client/oauth.go:252

			setMCPRuntimeStateForContext(ctx, h.server.ID, "oauth_retrying", 0, "", "")
			return nil
		}
		if !permanent {
			return fmt.Errorf("refresh OAuth credentials: %w", refreshErr)
		}
		credential.AccessToken = ""
		credential.RefreshToken = ""
		credential.Expiry = time.Time{}
		if saveErr := putOAuthCredential(credential); saveErr != nil {
			logging.LogWarnf("mcp oauth: clear invalid credentials failed: %s", saveErr)
		}
	}
	if !interactive {
		setMCPRuntimeStateForContext(ctx, h.server.ID, "authorization_required", 0, "", "")
		return errOAuthAuthorizationRequired
	}
	if !slices.Contains(asm.CodeChallengeMethodsSupported, "S256") {
		return fmt.Errorf("OAuth authorization server does not support PKCE S256")
	}
	if len(asm.ResponseTypesSupported) > 0 && !slices.Contains(asm.ResponseTypesSupported, "code") {
		return fmt.Errorf("OAuth authorization server does not support the authorization code response type")
	}
	if len(asm.GrantTypesSupported) > 0 && !slices.Contains(asm.GrantTypesSupported, "authorization_code") {
		return fmt.Errorf("OAuth authorization server does not support the authorization code grant")
	}

	flowID := reusableOAuthFlowID(credential)
	if flowID == "" {
		flowID, err = secureRandomString(24)
		if err != nil {
			return err
		}
	}
	state, err := secureRandomString(24)
	if err != nil {
		return err

View on GitHub (pinned to 9f775e8a12)