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
- Change the revocation endpoint to an https:// URL in the OAuth server metadata or credential configuration
- If testing locally, serve revocation on 127.0.0.1/localhost over plain HTTP, which is allowed
- 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
- Always provision OAuth metadata over HTTPS and audit http:// endpoints in configuration
- Only exempt loopback hosts for local development
- Keep discovery metadata fresh rather than hardcoding endpoint URLs
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
- generated image redirect is not allowed
- generated image URL must use HTTPS
- OAuth issuer mismatch
- --remote requires HTTPS
- Access to encrypted notebook data is not supported via this…
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)