21May, 2025
Switching Roles After Installation Might Break Your Experience Profile Dashboard, and More!
Ok I admit it. I took the easy way out. I was setting up a test environment of two instances using the standalone graphical installer and once done, I switched their roles. Everything worked except for one thing; the Experience Profile dashboard.
What was I doing?
I like to use the graphical setup when installing on a VM because it takes care of all dependencies, SQL, SOLR, etc. Once complete, I change the CM to its role and environment, like:
<add key="role:define" value="ContentManagement, Indexing, QA" />
and the CD as:
<add key="role:define" value="ContentDelivery, QA" />
Of course the CD needs its connection string file worked over so it points to the CM's instances for SQL, SOLR, but overall it's pretty simple.
Something must have changed because I've never had a problem with xDB. So, when I saw an error ribbon on the dashboard, I assumed yet another certificate issue, but instead it was role configuration.

Always Start With the Logs
The logs made things simple, showing a problem with connection strings.
URL https://qa-authoring.mnp.ca/sitecore/api/ao/v1/contacts/search?&pageSize=20&pageNumber=1&sort=visitCount desc&Match=*&FromDate=null&ToDate=null Exception System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: XConnect Client Configuration Connection string not found, connection string name: xconnect.search at Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetConnectionStringUri(String connectionStringName) at Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClientConnectionParametersFromConnectionString(String connectionStringName, String allowInvalidClientCertificatesAppSettingName, Uri& endpointUri, IHttpClientHandlerModifier[]& requestHandlers) at Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration..ctor(IModelConfiguration clientModel, String collectionConnectionStringName, String searchConnectionStringName, String configurationConnectionStringName, CircuitBreakerFactory circuitBreakerFactory, IRetryerRegistry retryerRegistry, String retryerName) --- End of inner exception stack trace ---
When trying the URL in the log all I get is:
{"message":"An error has occurred."}
Looking further, there's no entry for "xconnect.search" when checking the connection string file, so let's look deeper. A quick search finds the value we're looking for in the Sitecore.XConnect.Client.config file, where I can see the problem:
<!-- Collection and Search XConnect Client configuration for Standalone role --> <clientconfig type="Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration,Sitecore.XConnect.Client.Configuration" singleInstance="true" role:require="Standalone"> <param desc="clientModel" ref="xconnect/runtime" /> <param desc="collectionConnectionStringName">xconnect.collection</param> <param desc="searchConnectionStringName">xconnect.collection</param> <param desc="configurationConnectionStringName">xconnect.collection</param> <param desc="CircuitBreakerFactory" ref="xconnect/CircuitBreakersConfiguration"/> <param desc="retryerRegistry" type="Sitecore.Framework.TransientFaultHandling.IRetryerRegistry,Sitecore.Framework.TransientFaultHandling.Abstractions" resolve="true"/> <param desc="retryerName">Sitecore.XConnect.Client.Retryer</param> </clientconfig> <!-- Collection and Search XConnect Client configuration for ContentManagement role --> <clientconfig type="Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration,Sitecore.XConnect.Client.Configuration" singleInstance="true" role:require="ContentManagement"> <param desc="clientModel" ref="xconnect/runtime" /> <param desc="collectionConnectionStringName">xconnect.collection</param> <param desc="searchConnectionStringName">xconnect.search</param> <param desc="configurationConnectionStringName">xconnect.collection</param> <param desc="CircuitBreakerFactory" ref="xconnect/CircuitBreakersConfiguration"/> <param desc="retryerRegistry" type="Sitecore.Framework.TransientFaultHandling.IRetryerRegistry,Sitecore.Framework.TransientFaultHandling.Abstractions" resolve="true"/> <param desc="retryerName">Sitecore.XConnect.Client.Retryer</param> </clientconfig>
Reading into this, the instance started off as Standalone, causing the "xconnect.collection" connection string to be used. When switching to ContentManagement, the "xconnect.search" string is referenced, but it doesn't exist.
Patch for the Win
I admit my laziness, but at least I'm not going to modify the OOTB files, which should never be done. I've created a patch for this scenario you can use as well, which did the trick for me. Once deployed the dashboard worked as expected!
<?xml version="1.0"?> <sitecore> <xconnect> <clientconfig type="Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration,Sitecore.XConnect.Client.Configuration" singleInstance="true" role:require="ContentManagement and QA"> <param desc="searchConnectionStringName">xconnect.collection</param> </clientconfig> </xconnect> </sitecore> </configuration>