HL7 MSA Message Acknowledgment
HL7 field reference MSA fields from HL7 v2.5.1 Show fields
These are the generated fields for the version selected at the top of the page. The document stays the same, but the reference panel follows that version.
Fields
The MSA segment is the little receipt that comes back in an HL7 ACK message. If the MSH is the envelope, MSA is the part that says "yes, I got that", "I got it but there is a problem", or "no, I am not accepting that message at all". It is short, but it is one of the most important segments in a live interface because it controls whether the sender keeps moving, retries, alerts someone, or stops the queue.
Most production ACKs are really about the first two fields. MSA-1 is the acknowledgement code, and MSA-2 is the original message control ID that this ACK is answering. MSA-3 sometimes carries a friendly bit of text. The remaining fields are either old, specialised, or better handled by the ERR segment now. That does not make them useless, but it does mean you should know why you are using them before building logic around them.
One thing to keep straight: an ACK is not always the final business outcome. It may mean the receiving interface accepted the message, or it may mean the downstream application processed it, depending on how the connection is configured. In order workflows, for example, an order can be acknowledged at the transport level and still have an order response later. The MSA tells you about the acknowledgement layer you are looking at, not magically about every workflow that might happen afterwards. This is where operational tooling matters: in Integration Soup, I want the ACK rule, retry rule, and alerting rule to tell the same story.
Original mode and enhanced mode
A lot of everyday HL7 uses original acknowledgment mode. In that world you usually see AA, AE, or AR in MSA-1. AA means application accept, AE means application error, and AR means application reject. It sounds simple, and usually it is, as long as both sides agree what "processed" means for that interface.
Enhanced acknowledgment mode adds another layer. The receiver can send a commit acknowledgement first, using CA, CE, or CR, then later send the application acknowledgement using AA, AE, or AR. MSH-15 and MSH-16 are the fields that request those behaviours. In real interfaces, enhanced mode is less common than the standard makes it look, but you absolutely need to recognise the codes when they appear. Treating CA as if it means the order was fully processed is a very easy way to be confidently wrong.
A normal success and a useful failure
For a successful message, the ACK can be almost boring. The important thing is that MSA-2 echoes the original MSH-10. The ACK's own MSH-10 should be a new message control ID for the ACK itself. Those two values are easy to mix up, and when they are mixed up the sender may sit there saying "I never got my ACK" even though a message did come back. Open a request and ACK pair in HL7 Soup Web and check those two IDs before blaming the network.
For a failed message, I like MSA-3 to be readable and the ERR segment to be specific. MSA-3 might say "Validation failure". ERR can say which field failed, which HL7 error code applies, the severity, and a diagnostic message a support person can act on. If all the useful detail is buried in MSA-3 as free text, your monitoring system has to become a small literary critic.
How I tend to handle ACKs
Store the outbound message control ID, match it against incoming MSA-2, and keep the ACK's own MSH-10 as a separate identifier. That gives you clean correlation, retries, audit trails, and troubleshooting. If the ACK comes back with the wrong MSA-2, do not casually mark the message as successful. It might be an ACK for another message, an ACK built incorrectly, or a response from the wrong conversation.
Also be careful with retry logic. A timeout is often a retry candidate. A locked record or temporary internal error may be a retry candidate if the receiver has agreed that behaviour. A required field missing, unsupported message type, or bad table value is not fixed by sending the exact same message five more times with increasing optimism. ACK handling is not just "AA good, everything else resend". It is an interface agreement, a queue policy, and a support workflow.
So let's go through each of the MSA fields and talk about how they tend to behave in real interfaces.
This is the field everyone watches. In original mode, AA is application accept, AE is application error, and AR is application reject. In enhanced mode, CA, CE, and CR are the commit-level versions. The table is small, but the meaning depends heavily on the ACK mode, the connection configuration, and where the receiver chooses to generate the ACK.
I normally treat AA as success for the layer being acknowledged, not as a promise that every downstream business process is complete. AE means the receiver understood enough to say something went wrong while processing. AR is more of a "this message is not acceptable here" answer, such as unsupported message type, bad processing ID, unsupported version, or a structural problem. In practice, many systems use AE for almost every failure, so your handling should not rely on a perfect philosophical split between error and reject.
For monitoring, show the exact code. Do not hide CE and CR under a generic failure label if your interface uses enhanced mode. A commit error means the receiving system did not even commit the message for later processing. An application error means it got further and failed in the application layer. That distinction can decide whether the right fix is network, queue, parsing, data quality, or a downstream application issue.
Here is the field that makes the ACK belong to a particular message. It should contain the original message's MSH-10, exactly enough for the sender to match the response to the message it sent. The ACK's own MSH-10 is different. It identifies the ACK message. MSA-2 identifies the message being acknowledged.
This matters even on a simple MLLP connection where messages usually go one-at-a-time. Retries, queue restarts, interface engines, multiple routes, and support tools all depend on good correlation. If you generate ACKs yourself, this is one of the fields to test first. Send message MSG00001, make sure the response contains MSA|AA|MSG00001, and make sure the ACK header has its own new control ID. It is a small check that catches a surprising number of bad ACK implementations.
A short human message can be helpful, especially when someone is looking at an ACK list and trying to decide what happened. You will see values like Message accepted, Patient not found, Required field missing, or Unsupported message type. That is all fine as a readable summary.
I would not make automation depend on this field. It is free text, older guidance has moved structured error detail into ERR, and different systems phrase the same problem in different ways. Use it for a friendly explanation, then put the coded error, location, severity, and diagnostic detail in ERR where a system has a fighting chance of understanding it.
One more practical note: be careful what you echo back. An ACK is often logged in more places than the original message, because it is treated as operational noise. Do not copy sensitive patient data into MSA-3 just because it makes the message easier to read.
This belongs to HL7's sequence number protocol. If sequence numbering is being used, the receiver can tell the sender which sequence number it expects next. It is a way of keeping two systems lined up when they are tracking message order explicitly.
Most modern interfaces you will meet do not use this field. They rely on MLLP behaviour, message control IDs, queues, retry rules, and duplicate detection rather than the old sequence number protocol. If a partner does use MSA-4, document the whole sequence story: where the sequence number is sent, how it is reset, what happens after a timeout, and how the two sides recover when they disagree. A lone number in MSA-4 without the rest of that agreement is more puzzle than protocol.
This is one of those fields that mostly exists so old messages can still be understood. In the v2.5.1 data we use here, its data type is NUL, which is HL7's way of saying this field is not intended to be populated. Older delayed acknowledgment patterns were replaced by clearer acknowledgement modes and proper response messages.
For a new interface, I would leave it empty. If you need a fast receipt followed by later application processing, look at enhanced acknowledgements, order response messages, status updates, or whatever message pattern the workflow actually calls for. Do not try to resurrect delayed acknowledgement behaviour with MSA-5 unless you are maintaining a legacy partner that already requires it.
Before ERR became the better home for structured error detail, MSA-6 could carry a coded error condition. You may still see values from HL7 Table 0357, such as 101^Required field missing^HL70357, 102^Data type error^HL70357, 103^Table value not found^HL70357, or 200^Unsupported message type^HL70357.
It is useful to understand MSA-6 when reading older ACKs, but I would not make it the main place for errors in a new v2.5.1-style interface. Send a readable MSA-3 if you want one, then use ERR for the field location, HL7 error code, severity, application error code, diagnostic text, and user-facing message. That gives support people something precise to work with and gives automated tooling something less fragile than a sentence.
What about MSA-7 and MSA-8?
You may see newer references that show message waiting number and message waiting priority as MSA-7 and MSA-8. Those fields are about queued messages waiting to be retrieved by a polling application. The v2.5.1 segment table used by this tutorial stops at MSA-6, so I have kept the field list here to that version. If you are integrating with a newer profile that uses MSA-7 or MSA-8, treat them as a very specific polling/queue signal, not as part of the normal ACK success or failure decision.