siyuan-note/siyuan · error

OAuth revocation endpoint returned

Error message

OAuth revocation endpoint returned %s

What it means

The OAuth revocation endpoint replied with a non-2xx status while revoking the refresh or access token. The HTTP status text is wrapped in the returned error and joined across both token revocation attempts; revocation failure is also logged as a warning but still returned to the caller.

Solutions

  1. Read resp.Status in the error and check the IdP logs for the actual rejection reason
  2. If the token was already revoked, treat the outcome as idempotent success on your side and ignore the joined error
  3. Re-fetch OAuth discovery metadata so RevocationEndpoint matches the current server
  4. Confirm client_id/client_secret sent with the revocation request are accepted by the IdP
Defensive patterns

Strategy: try-catch

Validate before calling

resp, err := client.Post(revocationEndpoint, "application/x-www-form-urlencoded", strings.NewReader(body))
if err == nil && resp.StatusCode >= 200 && resp.StatusCode < 300 {
    // safe to proceed
}

Try / catch

err := revokeOAuthCredential(ctx, client, cred)
if err != nil {
    var statusErr interface{ Error() string }
    if strings.Contains(err.Error(), "OAuth revocation endpoint returned") {
        // token may already be revoked; log and treat as best-effort
        logging.LogWarnf("revocation non-2xx, continuing: %s", err)
    }
}

Prevention

When it happens

Trigger: POST to the revocation endpoint returns 400/401/404/5xx — e.g. the token was already revoked, the client credentials are wrong for RFC 7009 revocation, or the endpoint path in server metadata is stale.

Common situations: Revoking an already-expired/revoked token (some IdPs return 400), IdP rotated its revocation path, clock/auth issues causing 401, or the IdP not implementing RFC 7009 at the advertised endpoint.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

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

		}
		values := url.Values{"token": {token.value}, "token_type_hint": {token.hint}}
		applyOAuthClientAuthentication(values, nil, credential)
		req, err := http.NewRequestWithContext(ctx, http.MethodPost, credential.RevocationEndpoint, strings.NewReader(values.Encode()))
		if err != nil {
			result = errors.Join(result, err)
			continue
		}
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		applyOAuthClientAuthentication(nil, req, credential)
		resp, err := client.Do(req)
		if err != nil {
			result = errors.Join(result, err)
			continue
		}
		io.Copy(io.Discard, io.LimitReader(resp.Body, 1<<20))
		resp.Body.Close()
		if resp.StatusCode < 200 || resp.StatusCode >= 300 {
			result = errors.Join(result, fmt.Errorf("OAuth revocation endpoint returned %s", resp.Status))
		}
	}
	if result != nil {
		logging.LogWarnf("mcp oauth: revoke credentials failed: %s", result)
	}
	return result
}

func isSecureOAuthEndpoint(endpoint string) bool {
	parsed, err := url.Parse(endpoint)
	if err != nil {
		return false
	}
	if parsed.Scheme == "https" {
		return true
	}
	if parsed.Scheme != "http" {
		return false

View on GitHub (pinned to 9f775e8a12)