Alex Marshall
Alex Marshall

Reputation: 10322

How to resolve a name conversion failure when sending MSMQ messages

I've recently been following this article on how to set up a 3-party queueing system with MSMQ, wherein the publisher, queue server and subscriber are all on separate systems within an Active Directory domain. I've succeeded in completing Part 1 and the first half of Part 2. However, when I continue with the latter half of Part 2 and enable Transport security, I receive the following error: An error occurred when converting the 'mymsmqservermachine.mydomain.network.ads\private$\Path/To/MyQueuedService.svc' queue path name to the format name: Unrecognized error -1072824300 (0xc00e0014). All operations on the queued channel failed. Ensure that the queue address is valid. MSMQ must be installed with Active Directory integration enabled and access to it is available.

I've verified the following:

  1. Active Directory Integration for MSMQ is enabled on all the machines in the 3-party system, per this StackOverflow post.
  2. The URL to the queue remains exactly the same as it was prior to enabling security, which worked just fine, no parsing errors whatsoever.
  3. I've following the instructions provided by Windows when installing MSMQ here.

The relevant parts of the stack trace I get are:

at System.ServiceModel.Channels.MsmqFormatName.FromQueuePath(String queuePath)
   at System.ServiceModel.Channels.MsmqUri.ActiveDirectory.UriToFormatName(Uri uri)
   at System.ServiceModel.Channels.MsmqOutputChannel.OpenQueue()
 --- End of inner exception stack trace ---

Server stack trace: 
   at System.ServiceModel.Channels.MsmqOutputChannel.OpenQueue()
   at System.ServiceModel.Channels.MsmqOutputChannel.OnOpenCore(TimeSpan timeout)
   at System.ServiceModel.Channels.MsmqOutputChannel.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult.InvokeOpen()
   at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult..ctor(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.CommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.ServiceChannel.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult.InvokeOpen()
   at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult..ctor(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.CommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.BeginCall(ServiceChannel channel, TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.BeginCallOnce(TimeSpan timeout, CallOnceManager cascade, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.ServiceChannel.BeginEnsureOpened(TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureOpen(Boolean completedSynchronously)
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishEnsureInteractiveInit(IAsyncResult result, Boolean completedSynchronously)
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureInteractiveInit()
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.Begin()
   at System.ServiceModel.Channels.ServiceChannel.BeginCall(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, TimeSpan timeout, AsyncCallback callback, Object asyncState)
   at System.ServiceModel.Channels.ServiceChannel.BeginCall(ServiceChannel channel, ProxyOperationRuntime operation, Object[] ins, AsyncCallback callback, Object asyncState)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl[TArg1,TArg2,TArg3](Func`6 beginMethod, Func`2 endFunction, Action`1 endAction, TArg1 arg1, TArg2 arg2, TArg3 arg3, Object state, TaskCreationOptions creationOptions)
   at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateTask(ServiceChannel channel, ProxyOperationRuntime operation, Object[] inputParameters)
   at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateTask(ServiceChannel channel, IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

Based on the content of the stack trace, it appears that the failure is coming from resolving the queue name within Active Directory. I've tried the following to attempt to resolve such a failure:

  1. Simplifying the name to contain no periods or slashes (didn't work)
  2. Using a public queue instead of a private queue, in the event that this step was omitted from the original tutorial on MSDN (it wasn't, didn't work)

At this point, I'm out of ideas. Has anybody encountered this error when using WCF with net.msmq bindings before and solved their issue ?

EDIT: When running the following test code from the same machine and same user, I'm able to send a message to the queue perfectly fine:

Me.TestContext.WriteLine("Executing under user '{0}'", WindowsIdentity.GetCurrent().Name)

Dim msg = New System.Messaging.Message()

msg.Body = "This is a test message"
msg.Label = "Test Message"
msg.Formatter = new ActiveXMessageFormatter()

Dim queue = new MessageQueue("FormatName:DIRECT=OS:mymsmqservermachine.mydomain.network.ads\private$\Path/To/MyQueuedService.svc")

queue.Send(msg)

Upvotes: 0

Views: 783

Answers (1)

Alex Marshall
Alex Marshall

Reputation: 10322

By pure fluke, I stumbled across the solution, and I recorded it in my blog.

The gist of the solution was that I had to add a DNS identity for my WCF endpoint binding in my client:

Dim endpointAddress = New EndpointAddress(queueUri, EndpointIdentity.CreateDnsIdentity(queueUri.Host))

Dim netMsmqBinding = New NetMsmqBinding With
{
    .Durable = true,
    .ExactlyOnce = false,
    .UseActiveDirectory = false,
    .Security = New NetMsmqSecurity With
    {
        .Mode = NetMsmqSecurityMode.Transport
    }
}

Return New ChannelFactory(Of ICwteCentralPublishingServiceChannel)(netMsmqBinding, endpointAddress)

I apologize to the world for the Visual Basic code, it's a legacy application and wasn't my choice.

Upvotes: 0

Related Questions