Two WCF services listening on Endpoint using NamedPipes can thrown EndpointNotFoundException
Some time ago, I was helping out a team of developers that after testing this new WCF Service in their developement environment they went out and deployed this amazing piece of Software code and sudenly they started to see this really aboying error:
System.ServiceModel.EndpointNotFoundException:
There was no endpoint listening at net.pipe://localhost/AmazingWCFService/WonderfullDefaultPipe that could accept the message.
This is often caused by an incorrect address or SOAP action.
See InnerException, if present, for more details.
So, we went to the usual rabit hole troubleshooting this and sure enough we found out that there was an issue caused by another WCF Service using also a NamedPipe blocking the access to the Enpoint to all teh other all other possible WCF Services.
Knowing this, we tried to run their new WCF Service with elevetaed privileges and the issue was solved.
Of course that the story does not ends here, because other questions arise for sure:
- Question 1 : Why this is hapenning?
- Question 2 : And if I do not want to run my WCF Service with elevated privileges?
So, lets try to get our answers, imagine the following.
Starting service1.exe with admin privileges creates a memory mapped file with section name
\BaseNamedObjects\net.pipe:EbmV0LnBpcGU6Ly8rLw==
This name would be in the global name space, because the process runs with SeCreateGlobalPrivilege ( see output of whoami /all)
Now, Service2.exe is started without SeCreateGlobalPrivilege, and therefore the name is created in the session specific name space
\Sessions\2\BaseNamedObjects\net.pipe:EbmV0LnBpcGU6Ly8rL1NFUlZJQ0UyLw==
What happens then?
Starting client1.exe without admin rights connects to service1.exe running with admin right -> behavior is correct
Running client1.exe with admin right connects to service1.exe with admin rights -> behavior is correct
Starting client2.exe without admin rights is throwing an exception (Endpoint not found exception)
Client2.exe with admin right throws the same exception.
If you stop service1.exe, client2.exe will be able to talk to service2.exe, regardless if client2.exe is running with or without admin rights.
So the question is:
Why can’t client2 talk to service2, if service1 is running with admin rights?
And the answer is that everything will work correctly, if both services are running without admin rights, or if both services are running with admin rights.
To understand this lets look into more detail how behind the scenes th match of the Named Pipes is made.
Search sequence when the client of service2 tries to connect:
- Global\net.pipe://localhost/service2
- Global\net.pipe://localhost/
- Local\net.pipe://localhost/service2
- Local\net.pipe://localhost/
Now the solution....
Microsoft added an app setting for this issue in 4.6.2.
You can enable the below app setting in the client’s config to tell it to look for the best matching named pipe endpoint, so it won’t get intercepted by the elevated service.
<configuration> <appSettings> <add key="wcf:useBestMatchNamedPipeUri" value="true" /> </appSettings> </configuration>
You can find details in the WCF section of what’s new in 4.6.2.
Hope that helps