siyuan-note/siyuan · error

OAuth revocation endpoint must use HTTPS or loopback HTTP

Error message

OAuth revocation endpoint must use HTTPS or loopback HTTP

What it means

revokeOAuthCredential refuses to send OAuth token revocation requests to an endpoint that is neither HTTPS nor loopback HTTP. This guards refresh/access tokens from being leaked over unencrypted or non-local transport when an MCP client's OAuth server metadata supplies a weak revocation endpoint.

Solutions

  1. Change the revocation endpoint to an https:// URL in the OAuth server metadata or credential configuration
  2. If testing locally, serve revocation on 127.0.0.1/localhost over plain HTTP, which is allowed
  3. Verify the credential's RevocationEndpoint field is populated from trusted, current discovery metadata rather than stale config

Example fix

// before
credential.RevocationEndpoint = "http://internal-idp.local/revoke"
// after
credential.RevocationEndpoint = "https://internal-idp.local/revoke"
Defensive patterns

Strategy: validation

Validate before calling

func isRevocationEndpointSafe(raw string) bool {
    u, err := url.Parse(raw)
    if err != nil || u.Host == "" {
        return false
    }
    if u.Scheme == "https" {
        return true
    }
    host := u.Hostname()
    return u.Scheme == "http" && (host == "127.0.0.1" || host == "localhost" || host == "::1")
}

Prevention

When it happens

Trigger: An oauthCredential whose RevocationEndpoint URL uses plain http:// on a non-loopback host (or a scheme like ws://) is passed to revokeOAuthCredential via the OAuth credential cleanup path of the MCP client.

Common situations: A self-hosted OAuth provider behind plain HTTP on a LAN address; hand-edited or mocked server metadata with http:// URLs; a dev/test issuer accidentally configured in production.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

			for _, credential := range credentials {
				if err := revokeOAuthCredential(ctx, client, credential); err != nil {
					revokeErr = errors.Join(revokeErr, err)
				}
			}
			if revokeErr != nil {
				logging.LogWarnf("mcp oauth: revoke credentials for server [%s] failed: %s", serverID, revokeErr)
			}
		}()
	}
	return nil
}

func revokeOAuthCredential(ctx context.Context, client *http.Client, credential oauthCredential) error {
	if credential.RevocationEndpoint == "" {
		return nil
	}
	if !isSecureOAuthEndpoint(credential.RevocationEndpoint) {
		return fmt.Errorf("OAuth revocation endpoint must use HTTPS or loopback HTTP")
	}
	var result error
	for _, token := range []struct {
		value string
		hint  string
	}{{credential.RefreshToken, "refresh_token"}, {credential.AccessToken, "access_token"}} {
		if token.value == "" {
			continue
		}
		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)

View on GitHub (pinned to 9f775e8a12)