Tencent/WeKnora · error
dynamic client registration failed: %w
Error message
dynamic client registration failed: %w
What it means
Wraps a failure from the OAuth handler's dynamic client registration (RFC 7591) performed when no client is stored for the service. StartAuthorization registers a new client with the provider; if the provider rejects or the registration HTTP call fails, the error is wrapped and the authorization flow aborts before producing an authorize URL.
Source
Thrown at internal/mcp/oauth_manager.go:106
) (authorizationURL, attemptID string, err error) {
if !service.AuthConfig.IsOAuth() {
return "", "", fmt.Errorf("MCP service %s does not use OAuth", service.ID)
}
principal = principal.Normalize()
if !principal.Valid() {
return "", "", fmt.Errorf("principal context is required to authorize OAuth MCP service %s", service.ID)
}
h, err := m.newHandler(ctx, service, tenantID, principal, redirectURI)
if err != nil {
return "", "", err
}
// Register a client dynamically if we don't have one yet for this service.
existing, _ := m.repo.GetClient(ctx, tenantID, service.ID)
if existing == nil {
if err := h.RegisterClient(ctx, clientRegistrationName); err != nil {
return "", "", fmt.Errorf("dynamic client registration failed: %w", err)
}
clientID := h.GetClientID()
if clientID == "" {
return "", "", fmt.Errorf("dynamic client registration returned an empty client_id")
}
if err := m.repo.SaveClient(ctx, &types.MCPOAuthClient{
TenantID: tenantID,
ServiceID: service.ID,
ClientID: clientID,
RedirectURI: redirectURI,
}); err != nil {
logger.GetLogger(ctx).Warnf("failed to persist MCP oauth client: %v", err)
}
}
verifier, err := transport.GenerateCodeVerifier()
if err != nil {
return "", "", fmt.Errorf("failed to generate PKCE verifier: %w", err)View on GitHub (pinned to 988cbb0330)
Solutions
- Confirm the provider supports RFC 7591 dynamic registration and exposes registration_endpoint in its metadata
- Register a client manually with the provider and seed m.repo.SaveClient so GetClient returns non-nil
- Check the wrapped cause for HTTP status/timeouts; verify outbound network/SSRF policy allows the provider URL
- Fix provider-side registration requirements (e.g. required client metadata fields, software statement)
Example fix
// before
clientID := h.GetClientID()
if clientID == "" {
return "", "", fmt.Errorf("dynamic client registration returned an empty client_id")
}
// after: fall back to a statically configured client
clientID := h.GetClientID()
if clientID == "" {
if cfgClient := config.StaticOAuthClient(service.ID); cfgClient != "" {
clientID = cfgClient
} else {
return "", "", fmt.Errorf("dynamic client registration returned an empty client_id")
}
} Defensive patterns
Strategy: fallback
Validate before calling
// pre-flight: check provider metadata advertises dynamic registration
meta, err := fetchProviderMetadata(ctx, *svc.URL)
if err != nil || meta.RegistrationEndpoint == "" {
return fmt.Errorf("provider does not support dynamic registration; configure a static client")
} Try / catch
_, _, err := mgr.StartAuthorizationForService(ctx, svc, tenantID, principal, redirect, "")
if err != nil && strings.Contains(err.Error(), "dynamic client registration failed") {
// fall back to pre-registered client credentials from config
return startAuthorizationWithStaticClient(ctx, svc, config.StaticClientFor(svc.ID))
} Prevention
- Confirm the IdP supports RFC 7591 before relying on dynamic registration
- Seed MCPOAuthClient rows for providers known not to support it
- Whitelist provider registration endpoints in outbound/SSRF policy
- Log registration HTTP failures with provider response bodies for triage
When it happens
Trigger: First OAuth start for a service (no stored MCPOAuthClient), h.RegisterClient hits the provider's registration endpoint and fails: 4xx from provider, discovery metadata missing registration_endpoint, network/SSRF-guard block, timeout.
Common situations: Provider does not support dynamic client registration (returns 400/401/404 on /register); registration_endpoint absent from the provider's metadata; outbound firewall/SSRF guard blocks the registration URL; provider requires pre-registered client credentials instead.
Related errors
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/33b82fcdc5aae3ae.
Report an issue: GitHub.