Every IBM MQ message carries a twenty-four-byte MsgId in the message descriptor—a fingerprint for that message instance on the queue manager. Operations teams search by MsgId when a payment is stuck; developers save MsgId from the request put to pair replies; architects store MsgId in deduplication tables for exactly-once processing. MQ can generate MsgIds for you, or applications can supply their own with strict rules. This page explains MQMI_NONE, manual assignment, relationship to CorrelId and GroupId, report and dead-letter headers, COBOL and Java mapping, duplicate redelivery scenarios, and logging practices that make MsgId useful instead of decorative.
When the putting application sets MsgId to MQMI_NONE (or equivalent in the client), the queue manager assigns a value before the put completes. The value is unique in the sense required for messaging operations on that queue manager—do not use it as a global enterprise UUID across decades without checking collision policies. After put returns, read MsgId from the MQMD—your program needs it for request/reply correlation and logs. Never assume you know MsgId before put unless you set it yourself.
| Field | Purpose |
|---|---|
| MsgId | Identifies this message instance |
| CorrelId | Links to another message or token |
| GroupId | Groups segmented messages |
| AccountingToken | Optional accounting trace (4 bytes) |
Some programs copy a business key into MsgId when it fits twenty-four bytes or hash longer keys. Benefits: logs align with business ids. Risks: two different puts with the same MsgId confuse support tools; dedup tables may reject legitimate retries. If you assign MsgId, document whether retries reuse the same value (idempotent retry) or generate new values (new attempt). Mainframe COBOL must map binary fields carefully—display in hex in logs to avoid EBCDIC misinterpretation.
Client puts request with generated MsgId R1. Server reads R1, puts reply with new MsgId R2 and CorrelId = R1. Client matches on CorrelId, not on reply MsgId. Storing R2 in audit tables helps trace both legs. Timeout handlers should log R1 when abandoning a wait so support can find orphan replies on the reply queue.
When a consumer MQBACKs, the same message instance returns with the same MsgId—dedup logic should treat that as the same message, not a new event. When a producer issues a new put after failure, MQ assigns a new MsgId unless the application forces reuse—that is a new instance even if payload is identical. Exactly-once processing distinguishes these cases with business keys plus MsgId.
Report options can generate feedback messages referencing the original MsgId. Dead-letter headers (MQDLH) embed context about why a message failed—original MsgId appears in support traces. Browse the DLQ with MQ or MO71 tools and record MsgId in incident tickets. Cross-queue-manager tracing may require correlating with CorrelId and PutDate when messages traverse channels.
1234567891011/* New message - let MQ assign */ MD.MsgId = MQMI_NONE MQPUT(...) /* Read assigned id */ log("put MsgId=%s", hex(MD.MsgId)) /* Reply */ saved = request.MD.MsgId reply.MD.CorrelId = saved reply.MD.MsgId = MQMI_NONE MQPUT(ReplyToQ, reply.MD, ...)
Every package gets a tracking sticker when the warehouse accepts it. The sticker is different for each package. If the truck returns the same package because the door was wrong, it keeps the same sticker. If you send a new package, you get a new sticker—even if the toys inside look the same.
Given MsgId in hex from a DLQ header, list steps to find the original put time and queue.
Table unique on MsgId only—does it handle MQBACK redelivery correctly?
Java client and COBOL server exchange request/reply. What must match besides CorrelId?
1. MQMI_NONE on put tells MQ to:
2. Reply message CorrelId should usually equal:
3. MsgId length in MQMD is:
4. Reusing MsgId for a brand-new order is: