MSMQ 3.0 too secure for you?

With lots of customers developing systems that use MSMQ across WANs, I find that I get a number of calls on problems getting messages through. Usually sending messages works a treat but pulling them back again doesn’t. The main reason for this is the tightening up of MSMQ’s use of RPC as documented in the Message Queuing security overview. The “Secured remote read” feature will need to be tweaked if you plan to work across forest boundaries – even if you don’t, this problem can appear in development where the test machines are in different forests to the production servers. As the article says:

Message Queuing 3.0 cross-forest clients on Windows Server 2003 family computers in non-trusted domains will use the secure remote read interface. By default, the Message Queuing 3.0 server requires domain clients to establish an encrypted channel, and such a channel cannot be established between non-trusted domains. Thus remote read requests from such clients will be rejected. To modify this default behavior and allow the Message Queuing server to accept domain clients that do not establish an encrypted channel, create a DWORD value Security\NewRemoteReadServerAllowNoneSecurityClient in the registry and set it to 1.

No, I don’t know why the registry value is so horrendously long.

Also, the article talks about the Security branch – make sure you use HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSMQ\Parameters\Security and NOT HKEY_LOCAL_MACHINE\SECURITY.

Update April 11th – This also seems to do the trick if you are using local accounts on machines in domains. That is, if you are logged in as a local admin, or the application/service is running under a local account, then you can’t create a secure channel and so remote reads won’t work. The workaround is to use domain accounts OR set NewRemoteReadServerAllowNoneSecurityClient=1.

Comments (41)

  1. Nine times out of ten this will not be the correct question. Whoever is asking REALLY means "How do I

  2. theshked says:

    the above change to the security settings will apply only after restart.

  3. MSDN Archive says:

    Hi Thesked,

    Yes, that’s correct. I don’t think that there are any registry changes that MSMQ (in common with most other services) monitors after startup.


    John Breakwell (MSFT)

  4. Julius says:

    Hi John,

    Thank for this blog.

    I have already set the value in my registry but im still fail to view all the messages in the queue. I also set the "ANONYMOUS LOGON" to have Full control.

  5. MSDN Archive says:

    Hi Julius,

    Could you please elaborate on what you are trying to do? How are you trying to access the messages in the queue – what format are you using for the queue name, for example?

    What errors were you getting – Access Denied?

    Where are the machines physically and what domains do they belong to?


    John Breakwell (MSFT)

  6. Jürgen says:

    Hi John,

    thanks for your Twitter answer. I’ve found your blog a few days ago, but I’ve still a problem sending messages from a client (WinXP) to a MSMQ 3.0 server (Win2003). The machines are in different domains. I’m trying to send a message to a remote private queue. The MSMQ service is installed in workgroup mode. The path used from client is "Formatname:DIRECT=OS:xxprivate$test".

    I’ve set the registry key as well, but I think this only applies to reading operations.

    I always get the following Exception:

    "Queue Service not available"

    MessageQueueErrorCode = System.Messaging.MessageQueueErrorCode.ServiceNotAvailable

    I don’t know what to do, because the product will be developed for a big enterprise and I’ve no impact on the AD.



  7. MSDN Archive says:

    Hi Jürgen,

    Are you talking different domains in one forest or different domains in different forests?

    To send a message to another forest using a DIRECT Formatname, you will just need to open up security on the remote queue (everyone+anonymous logon having ‘send’ permissions).

    If the other domain is in the same forest then you can set security tighter by giving ‘send’ permissions to the sending account.

    If you are installed in workgroup mode and you are sending to a private queue then you are not involving AD at all.

    You don’t say what line of code is generating the "Queue Service not available" exception. It *won’t* be the send() call. Are you trying to check the queue exists first, for example? Any of those types of calls will fail.


    John Breakwell (MSFT)

  8. Jürgen says:

    Hi John,

    I’m talking about different domains in different forest.

    The remote private queue security is wide open for both users "Everyone" and "Anonymous Logon". Both have nearly full control.

    I’ve read that in such a constellation no AD is involved and this is good, because there will be no trust setup for the participating domains.

    The code fragment looks like:


       public void TestSystemMessagingSend()




           NotificationRequest request = GenerateNotificationRequest();

           const string QUEUE_PATH = @"FormatName:DIRECT=OS:xxprivate$test";

           Message message = new Message(request, new XmlMessageFormatter(new[] {typeof (NotificationRequest)}))


                                 UseDeadLetterQueue = true,


           using (MessageQueue mq = new MessageQueue(QUEUE_PATH))






         catch (MessageQueueException mqex)





         catch (Exception ex)






    The Exception is thrown on Send().



  9. MSDN Archive says:

    Hi Jürgen,

    If you are seeing ServiceNotAvailable on a Send() operation, then that means the sending application is unable to contact the LOCAL MSMQ queue manager. The destination machine takes no part as we are just trying to put a message in an outgoing queue, not deliver it.

    Is MSMQ installed and running on the local machine?

    Is the sender installed as an Independent client? (which options did you pick to install MSMQ?)


    John Breakwell (MSFT)

  10. Jürgen says:

    Hi John,

    as far as I see we’ve localized the problem right now. On the test client machine was <b>no</b> MSMQ installed! I’ve installed it in workgroup mode as well and started it. Everything works fine now, BUT is there any possibility to send and / or recieve messages without installing MSMQ on every client machine?



  11. MSDN Archive says:

    Hi Jürgen,

    You need MSMQ installed at both ends.

    In theory you could write an application that put MSMQ shaped packets on the wire (the protocol has been published) and so avoid the need for an installed queue manager but that’s a serious/hard-core endeavour.


    John Breakwell (MSFT)

  12. Jeff says:

    I am having similar troubles.  We have a classic ASP page running on a Windows 2000 box.  It has MSMQ version 2.0 (5.0).  It is calling a Queue on a Windows 2003 box running MSMQ version 3.0 (5.2).  I have changed the registry setting and the security for Everyone and ANONYMOUS_LOGIN on the 2003 Box’s queue to full control.

    Still no love.  My fear is that 2.0 and 3.0 are not going to play nice.  They are within the same domain, but Classic ASP is notorious lax about passing security info.

    Any suggestions, or am I tilting at windmills here.  Thanks!

  13. MSDN Archive says:

    Hi Jeff,

    If you have set security on the queue for Everyone and Anonymous Logon then you do not have a permissions problem.

    There are no security problems with message transfer between MSMQ 2.0 and 3.0.

    You don’t say if you are sending messages to the remote queue or receiving them. Ths registry value only applies to receiving messages from remote queues.

    What errors do youy see?


    John Breakwell (MSFT)

  14. Jeff says:

    Error Message:

    MSMQQueueInfo error ‘c00e0003’

    The queue does not exist, or you do not have sufficient permissions to perform the operation.

    /mysite/mypage.asp, line 36

    This asp page is sending the request on line 36:

    The code is:

    set qSend = qInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  15. MSDN Archive says:

    Hi Jeff,

    As you have switched off queue-level security (with everyone/anonymous logon) then permissions shouldn’t be a problem so I would suggest you are not addressing the queue correctly. What is the full address you are passing to the qInfo object?


    John Breakwell

  16. Jeff says:

    The opbject is created, and the properties are defined like so:

    set qInfo = server.CreateObject("MSMQ.MSMQQueueInfo")

    set mSend = server.CreateObject("MSMQ.MSMQMessage")

    qInfo.PathName = glscQueueNameDecoder

    qInfo.Label = glscQueueLabelDecoder

    These Global Constants are defined in an include page as follows:

    glscQueueNameDecoder = QueueServerName & "MIMEDecoderQueue"

    OHQueueServerName = "Parser2"

    glscQueueLabelDecoder = "MIME Decoder Queue"

    An apology here.  This is not my code….  

  17. Jeff says:

    I have tried passing in the following:

    ‘glscQueueNameDecoder = "OS:Parser2MIMEDecoderQueue"

    glscQueueNameDecoder = "TCP:"

    But to no avail.

  18. MSDN Archive says:


    So the pathname to the queue is "Parser2MIMEDecoderQueue". Parser2 is the Windows 2003 server, yes?

    The MSMQ Queue Manager on the sender will lookup this address in Active Directory. If it cannot find Parser2 (as a computer object) or MIMEDecoderQueue (as a *public* queue object) then an error will be returned. Can you see both of these objects using "Active Directory: Users and Computers"? (You will need to enable "Advanced Features" and "Users, Groups, and Computers as containers"). I assume you have been setting queue permissions using Computer Management.

    You have said that the Windows 2000 and 2003 machines are both in the same domain but are they using the same DC server? Check the  HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSMQParametersMachineCacheCurrentMQISServer registry value.


    John Breakwell (MSFT)

  19. MSDN Archive says:

    Hi Jeff,

    These won’t work:

    ‘glscQueueNameDecoder = "OS:Parser2MIMEDecoderQueue"

    glscQueueNameDecoder = "TCP:"

    because you are specifying a pathname (qInfo.PathName) but supplying a (incomplete) formatname (OS:Parser2MIMEDecoderQueue).

    The corresponding formatnames would be




    If you wanted to use those, the code would need to use "qInfo.FormatName" instead.




  20. Jeff says:


    Parser2 is the Windows 2003 server.  I checked, and both objects exist in AD (as does the Windows 2000 Server, if that matters).  

    Unfortunately they are not using the same DCs.  (One is on dc01, the other on dc05).  The windows 2000 box has the registry entry for CurrentMQISServer, but it is set to an empty string.  The Windows 2003 box does not even have that registry setting in the MachineCache folder.

    Interestingly enough, I can not pull up the Properties for message queuing on the 2000 box.  I get the following error:

    Unable to obtain the security descriptor

    Error: the list (in the registry) of domain controllers that are running Message Queuing is empty.

    Which comes as no surprise.

    I have tried to set the registry value by hand and cycle the box, but it was reset to an empty string.

    Let me also say – that you so much for your help.  This was just dumped in my lap, and I was completely at sea with it.

  21. Jeff says:

    I am guessing that I will need to reinstall MSMQ on the 2000 Box, but I didn’t want to go that route until I got confirmation that this would help.

  22. MSDN Archive says:

    Hi Jeff,

    Reinstalling MSMQ would fix this problem but it would mean having to recreate any queues on the Windows 2000 machine.

    You could try setting the MQIS Server to be used with the StaticMQISServer registry value.( Make sure you use the correct syntax for the data.

    You might want to consider raising a support request with Microsoft too.


    John Breakwell (MSFT)

  23. Jeff says:

    I think we are going to try moving the Classic ASP page off the 2000 box and onto a new 2003 box.  I THINK that will fix the problem as then (as I understand it) we don’t need MSMQ running on a domain controller.  It all can be done through AD, Right?

    I will let you know how it turns out.

  24. MSDN Archive says:

    Hi Jeff,

    Moving to a new box would have the same result as reinstalling MSMQ on the old box.

    Yes, with Windows 2003 you won’t need MSMQ running on a domain controller. The client will use standard LDAP queries to a standard DC for the information it requires. As long as there are no other Windows 2000 clients around, you could uninstall MSMQ from any domain controllers (that weren’t also hosting any of your queues, of course!)


    John Breakwell (MSFT)

  25. Hi John,

    Is this registry setting works only for read/write operations? It helped me to be able to send message to the queue from one untrusted domain to another.

    I’m unable though to browse the private queues.

    public static MessageQueue[] GetPrivateQueuesByMachine(string machineName)


    gives "Access to Message Queing is denied"

    Looks like some Browse permission issue.

    It is installed in workgroup mode, and I do not have security tab  enabled for Messaging in MMC.

    Thank you

  26. MSDN Archive says:

    Hi Elena,

    The NewRemoteReadServerAllowNoneSecurityClient registry value is only for *read* operations. I don’t understand how it assisted you with sending messages from one untrusted domain to another. For such cross-forest communication I direct people to these other blog posts:

    If you cannot see a Security tab in Computer Management then that is probably because the logged-in user does not have the "Get permissions" permission for that queue. Log in with an account with more permissions (such as a local admin) and change the permissions to something less restrictive for the account you are trying to use.


    John Breakwell (MSFT)

  27. Mike says:


    I have a similar problem. I have a MSMQ Windows 2003 cluster. I have an ASP Page that gets an "Access is Denied" Error when it tries to call PeekCurrent(). The queue it is trying to Peek on has every user with full permissions. It can send messages to the queue just fine it just can’t seem to peek. Other processes are able to peek on this queue.

    Any Ideas?

  28. MSDN Archive says:

    Hi Mike,

    The important information I’ll need is:

    1) where is the ASP page hosted?

    2) where is the queue hosted (I assume in a clustered resource)?

    3) what are the permissions on the queue – have you just used Everyone or did you add Anonymous Logon as well?

    4) where are the other processes that work hosted?

    5) what account are the working processes running under?


    John Breakwell (MSFT)

  29. Mike says:

    Hi John,

    1) A Windows 2003 Web server.

    2) A Windows 2003 Cluster that is just an MSMQ server

    3) Every user has Full Control (Everyone Anonymous, etc)

    4) A Windowos 2003 Application server (four machines total, 1 web, 2 MSMQ clustered, 1 app)

    5) The processes that are working are working under various accounts (Local System, named users)

    Additional Information:

    I built a COM callable .NET component to try and see if this would resolve it. It is failing also with an exception but it has no description at System.Messaging.MessageQueue.MQCacheableInfo.get_ReadHandle()

    <rest of stack omitted>


    using (MessageQueue responseQ = new MessageQueue(qPath))




       using (MessageEnumerator msgEnum = responseQ.GetMessageEnumerator2())


        while (msgEnum.MoveNext()) //<– exception with out description happens here

  30. MSDN Archive says:

    Hi Mike,

    Typical – I missed (6) "Are the machines in same domain, different forests or different workgroups?"

    There are several boundaries that return "Access Denied" when making remote receive calls.

    1) The obvious one, queue level security

    2) Secure RPC, as documented on the above blog post (have you tried the registry value?)

    3) Firewalls that block the RPC protocol (

    4) Cross-forest security  (

    If none of these apply to your situation, you may be better off raising a support call with Microsoft.


    John Breakwell (MSFT)

  31. Mike says:


    A machines are in the same domain. I did try the registry value to no avail.

    Thanks for your help.


  32. MSDN Archive says:

    Hi Mike,

    If you set Anonymous Logon to Full control and tried the NewRemoteReadServerAllowNoneSecurityClient

    registry value then there aren’t any options I can think of left.

    In your test app, why don’t you do a simple remote receive using a DIRECT format name?

    Also try using a private queue.



  33. Mike says:


    All of my requests use the DIRECT format name. I have tried both private and public queues.

    Just for fun, I took the apps from my application server and put them on the web server. For some reason they can’t read from queues while on that machine either.

    I am baffeled.


  34. MSDN Archive says:

    Hi Mike,

    So you’ve narrowed it down to a problem with the machine. Could be a problem with the secure channel the machine sets up with a domain controller for security checks.

    Saw an incident like that with Windows XP:


    John Breakwell (MSFT)

  35. Mike says:

    Hello Again John,

    I am still having the issue with the ASP pages in IIS 6. I built a new web server and now I am able to call peek current from that machine from any process (a VB script, an exe, windows service) except IIS. I have some additional information and wanted to see if it might help you suggest a solution. Everytime I try to call peek current from IIS (no matter what user I use: domain admin, anaymous), I get a failure audit in the securty log like this.

    Privileged Service Called:

    Server: NT Local Security Authority / Authentication Service

    Service: LsaRegisterLogonProcess()

    Primary User Name: <machine>

    Primary Domain: <domain>

    Primary Logon ID: (0x0,0x3E7)

    Client User Name: <user>

    Client Domain: <domain>

    Client Logon ID: (0x0,0x212569)

    Privileges: SeTcbPrivilege

    If I call peek current from another process (in this case a vb script) I get a success audit like this

    Privileged Service Called:

    Server: NT Local Security Authority / Authentication Service

    Service: LsaRegisterLogonProcess()

    Primary User Name: <machine>

    Primary Domain: <domain>

    Primary Logon ID: (0x0,0x3E7)

    Client User Name: <machine>

    Client Domain: <domain>

    Client Logon ID: (0x0,0x3E7)

    Privileges: SeTcbPrivilege

    The only difference I see is that IIS passes the anaymous account while the vb script passes the machine name.

    Does this ring any bells for you?


  36. Mike says:

    In addition, after I get the SeTcbPrivilege error I get an object access error

    Object Open:

    Object Server: SC Manager

    Object Type: SC_MANAGER OBJECT

    Object Name: ServicesActive

    Handle ID: –

    Operation ID: {0,10821284}

    Process ID: 528

    Image File Name: C:WINDOWSsystem32services.exe

    Primary User Name: <machine>

    Primary Domain: <domain>

    Primary Logon ID: (0x0,0x3E7)

    Client User Name: <iis anaymous user>

    Client Domain: <machine>

    Client Logon ID: (0x0,0xA50FB9)

    Accesses: READ_CONTROL

    Connect to service controller

    Enumerate services

    Query service database lock state

    Privileges: –

    Restricted Sid Count: 0

    Access Mask: 0x20015

  37. MSDN Archive says:

    Hi Mike,

    So the problem with the initial web server have been resolved by replacing the machine.

    Now your non-IIS apps work properly on the web server when they didn’t before.

    I take it the security log snippets are from the web server, yes?

    SeTcbPrivilege is the "To Act as Part of the Operating System" privilege.

    This issue sounds like a problem with the account used by IIS to communicate with MSMQ – the IIS ‘guest’ account is insufficient.

    In your ASP code, are you impersonating the user that is calling the page?


    John Breakwell (MSFT)

  38. Mike says:


    Your assumptions are correct. Using the information you provided ("To Act as Part of the Operating System")  I have got this to work. However, my procedures are quite odd. Here is how I can get this to work.

    1) Stop IIS

    2) Set the Identity on the Application Pool to

    "Local System"

    3) On the Virtual Directory, select Properties – Directory Security – and Edit ‘Authentication and access control’

    4) Change the ‘Anonymous Access’ user to the Domain admin, enter the password, and ensure ‘Integrated Windows Authentication’ is checked. Click ok.

    5) Start IIS.

    6) Try to pull a message back from a queue (it should work) but I don’t want IIS running as a domain admin. So I….

    7) Stop IIS

    8) On the Virtual Directory, select Properties – Directory Security – and Edit ‘Authentication and access control’

    9) Change the ‘Anonymous Access’ user to the internet gust account user  <Machine_Name>IUSER_<MachineName>, leave the password blank, and ensure ‘Integrated Windows Authentication’ is checked. Click ok.

    10) Start IIS.

    11) It works. Even after reboots.

    Now I will be the first to admit that these steps shouldn’t do anything other than changing the identity on the App Pool to Local System, but for some reason it will only work if I enter the domain admin account, get it to work, and then change it back to the guest account. Thank you for all your help. If you would like more information I will check back and be happy to provide it.


  39. MSDN Archive says:

    Hi Mike,

    I’ll get one of my IIS colleagues to have a look.


    John Breakwell (MSFT)

  40. MSDN Archive says:

    Hi Mike,

    Yes, my IIS colleagues can’t see that you are doing anything more than change the identity on the App Pool. Defintely a strange problem.


    John Breakwell (MSFT)

  41. pedruskal says:


    I tried your solution but it didn’t help….

    – I got MSMQ 3.0 on WinXP Prof SP3 and .NET Framework 3.5 SP1.

    – I’m using private queues.

    – I want to access with 2 apps, one on the same machine as the MSMQ (I use MessageQueue.Create(".\Private$\queueName"), and I can read and write without problems), and another app which might be on the same PC or in the local network, so I’m trying to access to the locally created queues with "FormatName:DIRECT=TCP:<ip>\private$\queueName" and I actuall can write in the queues, locally and remotely, with this path.

    The problem comes when I want to read, the queue has canWrite=true and canRead=false..

    I’m trying it locally, so I’m using the loopback ip which I think should work (because I’m able to write).

    I looked at the queue properties and everybody has any permission..

    Any ideas?

    (I’m not using any authentication/encryption which doesn’t apply by default)

    Thank you!