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

  1. Confirm the provider supports RFC 7591 dynamic registration and exposes registration_endpoint in its metadata
  2. Register a client manually with the provider and seed m.repo.SaveClient so GetClient returns non-nil
  3. Check the wrapped cause for HTTP status/timeouts; verify outbound network/SSRF policy allows the provider URL
  4. 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

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.