MQRC 2016: Getting messages is inhibited
MQRC 2016 (MQRC_
Other names for this code
Also written as RC2016, reason code 2016, MQ 2016, MQ error 2016, MQRC_GET_INHIBITED, 07E0, 0x07E0, MQ get inhibited, GET(DISABLED), MQJE001 Reason 2016.
What it means
Every local, model and alias queue has a get attribute. In MQSC it is GET(ENABLED) or GET(DISABLED), and in the MQI it is called InhibitGet. While it is disabled, the queue manager refuses every MQGET on that queue, browse calls included. The call ends with completion code MQCC_
The application itself is usually fine. An administrator, a script or a control program disabled gets, often to hold messages while a downstream system is down or a change goes in. Puts normally keep working, so messages build up while the reader fails. If the application opened an alias queue, gets must be enabled on both the alias and the base queue at the moment of the MQGET. A disabled flag on either one gives 2016.
The attribute is checked on each get, not at open time. Disabling gets doesn't undo work already done either. A get that succeeded inside a unit of work can still be committed afterwards. The same reason code identifies the Get Inhibited event, which the queue manager writes to SYSTEM.
Common causes
- An administrator ran
ALTER QLOCAL(...) GET(DISABLED)to stop consumers during an outage or a deployment, and nobody enabled it again. - The application reads through an alias queue, and gets are disabled on the alias even though the base queue is fine (or the other way round).
- An automation job or runbook disables gets for a maintenance window, and the application started before the window closed.
- A control program called MQSET with the MQIA_
INHIBIT_ GET selector to pause processing. - The queue was rebuilt from a saved definition, such as dmpmqcfg output on distributed MQ or a CSQUTIL command file on z/OS, that still carried GET(DISABLED).
How to find the problem
- Check the queue and every alias in the path. In runmqsc, run
DISPLAY QLOCAL(ORDERS.IN) GET PUT CURDEPTH ALTDATE ALTTIME, and for an aliasDISPLAY QALIAS(ORDERS..ALIAS) GET TARGET - On z/OS, issue the same DISPLAY command from the console with the queue manager's command prefix, for example
-CSQ1 DISPLAY QLOCAL(ORDERS.IN) GET, or use the ISPF operations and control panels. - Compare ALTDATE and ALTTIME with the time the failures started. They show when the definition last changed.
- If command events are on (
DISPLAY QMGR CMDEV), SYSTEM.ADMIN. COMMAND. EVENT holds a record of the ALTER with the user ID that issued it. On z/OS the console log also shows the command. - If inhibit events are on (
DISPLAY QMGR INHIBTEV), each Get Inhibited event on SYSTEM.ADMIN. QMGR. EVENT names the queue and the application, and the channel and connection name for client applications.
How to fix it
- Find out why gets were disabled before changing anything. If an operator did it on purpose, agree with them when to turn it back on.
- Enable gets with
ALTER QLOCAL(ORDERS.IN) GET(ENABLED), orALTER QALIAS(...)for an alias. The change applies to the next MQGET, so applications don't need to reopen the queue. - Code the application to treat 2016 as temporary. Wait and retry with a growing interval rather than ending the program or writing an error for every attempt.
- Put the enable step in the same runbook as the disable step, and alert on Get Inhibited events so a forgotten pause is noticed quickly.
What it looks like
JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2016' ('MQRC_GET_INHIBITED').IBM documentation
IBM documentation: MQRC 2016. Use the documentation for your installed release.
Related codes
Questions
Are messages lost when I get MQRC 2016?
No. Messages already on the queue stay there, and puts usually keep working. Watch the depth, because a queue that keeps filling while gets are off will reach MAXDEPTH and start returning 2053 to the senders.
What is the difference between 2016 and 2051?
2051 (MQRC_PUT_INHIBITED) is the same control for puts. 2016 stops readers and 2051 stops writers. An administrator can set either one, or both, on the same queue.
Why did MQOPEN work but MQGET fail?
The get attribute is checked on each MQGET, not when the queue is opened. An open for input succeeds, and the failure comes on the first get after gets were disabled.