Tencent/WeKnora · error

MCP OAuth metadata URL failed SSRF validation: %w

Error message

MCP OAuth metadata URL failed SSRF validation: %w

What it means

ValidateServiceOutboundURLs in internal/mcp/security.go:31 wraps secutils.ValidateURLForSSRF when the MCP service's OAuth AuthServerMetadataURL fails SSRF validation. OAuth discovery fetches this metadata URL server-side, so a hostile URL could probe internal networks. The wrapped error names the concrete violation.

Source

Thrown at internal/mcp/security.go:31

// persistence boundaries and immediately before client construction so stale
// or imported rows cannot bypass the current SSRF policy.
func ValidateServiceOutboundURLs(service *types.MCPService) error {
	if service == nil {
		return fmt.Errorf("MCP service is required")
	}
	if service.URL != nil {
		serviceURL := strings.TrimSpace(*service.URL)
		if serviceURL != "" {
			if err := secutils.ValidateURLForSSRF(serviceURL); err != nil {
				return fmt.Errorf("MCP service URL failed SSRF validation: %w", err)
			}
		}
	}
	if service.AuthConfig != nil {
		metadataURL := strings.TrimSpace(service.AuthConfig.AuthServerMetadataURL)
		if metadataURL != "" {
			if err := secutils.ValidateURLForSSRF(metadataURL); err != nil {
				return fmt.Errorf("MCP OAuth metadata URL failed SSRF validation: %w", err)
			}
		}
	}
	return nil
}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Point AuthServerMetadataURL at a public https endpoint.
  2. Whitelist the internal IdP hostname via SSRF_WHITELIST if it is a trusted internal service.
  3. Fix the scheme to http/https and ensure the URL has a hostname.
  4. Inspect the wrapped error (invalid scheme / no hostname / SSRF validation failed) for the exact cause.

Example fix

// before
service.AuthConfig.AuthServerMetadataURL = "http://127.0.0.1:8080/.well-known/oauth-authorization-server"
// after
service.AuthConfig.AuthServerMetadataURL = "https://auth.example.com/.well-known/oauth-authorization-server"
// or whitelist 'auth.internal.corp' in SSRF_WHITELIST
Defensive patterns

Strategy: validation

Validate before calling

if svc.AuthConfig != nil && strings.TrimSpace(svc.AuthConfig.AuthServerMetadataURL) != "" {
    if err := secutils.ValidateURLForSSRF(strings.TrimSpace(svc.AuthConfig.AuthServerMetadataURL)); err != nil {
        return fmt.Errorf("unacceptable OAuth metadata URL: %w", err)
    }
}

Type guard

func hasHTTPSMetadataURL(ac *types.MCPAuthConfig) bool {
    return ac != nil && strings.HasPrefix(strings.TrimSpace(ac.AuthServerMetadataURL), "https://")
}

Prevention

When it happens

Trigger: CreateMCPService/UpdateMCPService/NewMCPClient/newHandler with service.AuthConfig non-nil and AuthServerMetadataURL non-empty after trimming, where the URL fails ValidateURLForSSRF (private/loopback host, non-http(s) scheme, empty hostname, blocked DNS).

Common situations: Configuring OAuth for an internally hosted identity provider (e.g. http://keycloak.internal/.well-known/oauth-authorization-server); using an http:// metadata URL pointing at localhost during local testing; SSRF_WHITELIST not including the internal IdP host.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/a90e0593444921c0. Report an issue: GitHub.