Tencent/WeKnora · error

MCP service %s does not use OAuth

Error message

MCP service %s does not use OAuth

What it means

Returned by StartAuthorization when the service's AuthConfig is not OAuth-based. Only services configured with OAuth auth can run the authorization-code flow; attempting to start one for a service using another auth type (API key, none, etc.) is rejected with the service ID in the message.

Source

Thrown at internal/mcp/oauth_manager.go:90

	}
	h := transport.NewOAuthHandler(cfg)
	h.SetBaseURL(*service.URL)
	return h, nil
}

// StartAuthorization performs discovery + (one-time) dynamic client
// registration, then returns the authorization URL and an opaque attempt ID.
// redirectURI is the backend callback URL registered with the auth server;
// frontendRedirect is where the callback bounces the browser when finished.
func (m *OAuthManager) StartAuthorization(
	ctx context.Context,
	service *types.MCPService,
	tenantID uint64,
	principal types.Principal,
	redirectURI, frontendRedirect string,
) (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()

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Switch the service's AuthConfig to OAuth before calling StartAuthorization
  2. Update the client to only render/start OAuth flows when the service auth type is oauth
  3. Check whether a stale service record was fetched; reload the service before the call
  4. Route API-key/bearer services through their own credential flow instead

Example fix

// before
url, id, err := manager.StartAuthorizationForService(ctx, svc, tenantID, principal, redirect, "")
// after
if !svc.AuthConfig.IsOAuth() {
    return fmt.Errorf("service %s uses %s auth; use the non-OAuth flow", svc.ID, svc.AuthConfig.Type)
}
url, id, err := manager.StartAuthorizationForService(ctx, svc, tenantID, principal, redirect, "")
Defensive patterns

Strategy: validation

Validate before calling

if !svc.AuthConfig.IsOAuth() {
    return fmt.Errorf("service %s uses non-OAuth auth; choose the matching flow", svc.ID)
}

Type guard

func isOAuthService(svc *types.MCPService) bool { return svc != nil && svc.AuthConfig.IsOAuth() }

Try / catch

if !isOAuthService(svc) { return useAlternativeAuthFlow(svc) }
if _, _, err := mgr.StartAuthorizationForService(ctx, svc, tenantID, principal, redirect, ""); err != nil {
    if strings.Contains(err.Error(), "does not use OAuth") { return useAlternativeAuthFlow(svc) }
    return err
}

Prevention

When it happens

Trigger: Calling AuthorizeURL or StartAuthorizationForService on a service whose AuthConfig.IsOAuth() returns false (e.g. auth type is api_key, bearer, or none).

Common situations: Frontend shows the 'Connect with OAuth' button for all services regardless of auth type; service auth type changed after deployment but cached client state still treats it as OAuth; copy/paste of OAuth setup code applied to an API-key service.

Related errors


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