HL7 ACK Codes Explained: AA, AE, and AR (MSA-1)
Hl7 Tools

HL7 ACK Codes Explained: AA, AE, and AR (MSA-1)

What an HL7 ACK Code Actually Communicates

In HL7 v2.x messaging, almost every message a system sends gets an acknowledgment (ACK) in return. The single most important field in that ACK is MSA-1, the Acknowledgment Code. It is a two-letter code that tells the sender, in unambiguous terms, what happened to the message: was it accepted, did it contain an error, or was it rejected outright? Getting these codes right is the difference between a reliable interface and one that silently drops patient data. This guide explains the three application-level codes โ€” AA, AE, and AR โ€” what each one means, when a receiver should send each, and how they relate to the older and newer code sets. For the broader picture of how acknowledgments flow, see HL7 ACK Messages Explained.

AA โ€” Application Accept

AA means "Application Accept." The receiving application got the message, understood it, and successfully processed it. This is the happy path: an ADT^A01 admit was recorded, an ORM order was queued, an ORU result was filed. When a sender receives AA, it can safely consider the transaction complete and move on. In a store-and-forward interface engine, AA is the signal to mark the message as delivered and remove it from the retry queue.

A critical nuance: AA asserts application-level success, not merely that the bytes arrived. A system that simply received a message but has not yet validated or stored it should not send AA. Sending AA prematurely is a common cause of phantom data loss โ€” the sender believes the message was processed and stops retrying, while the receiver later fails to commit it.

AE โ€” Application Error

AE means "Application Error." The receiver understood that a message arrived and could parse its structure, but something about its content prevented successful processing. Classic examples: a required field such as the patient identifier (PID-3) was missing, a coded value did not match any entry in the receiver's table, or a referenced order number did not exist. AE says, in effect, "I received your message, I see what you were trying to do, but I cannot complete it as sent โ€” fix the content and try again."

When a receiver sends AE, it should populate an ERR segment (or MSA-3 in older versions) describing what went wrong, so the sender or an integration analyst can diagnose it. An AE without a useful error description is one of the most frustrating things to debug; the article Debugging HL7 ACK Failures covers how to read these. The sender's correct response to AE is usually not to retry blindly โ€” the same content will fail again. It should be flagged for human review.

AR โ€” Application Reject

AR means "Application Reject." The receiver is refusing the message at a more fundamental level than AE. AR is appropriate when the problem is not a fixable content error but a structural or contextual one: an unsupported message type, a version mismatch, a message sent to the wrong system, or a sequence/processing error that makes the message invalid as a whole. Where AE says "this particular content is wrong," AR says "I should not be processing this message at all."

The practical distinction matters for retry logic. An AE often indicates a data-entry problem upstream that a human can correct and resubmit. An AR usually indicates a configuration or routing problem that no amount of resending will fix until someone changes the interface setup. Treating every negative acknowledgment the same way โ€” retrying both AE and AR indefinitely โ€” is a frequent cause of message storms that flood an interface engine.

AA vs AE vs AR at a Glance

  • AA (Accept): received, understood, processed successfully. Transaction complete.
  • AE (Error): received and understood, but the content could not be processed. Fix content, resubmit after review.
  • AR (Reject): received but refused โ€” wrong type, wrong version, wrong destination, or structural error. Fix configuration, not content.

You can see exactly where MSA-1 sits in a real message by pasting one into the HL7 viewer, and you can produce well-formed ACKs with the right code using the HL7 ACK generator.

The Other Code Set: CA, CE, and CR

If you have seen CA, CE, and CR in MSA-1, you have encountered HL7's "enhanced acknowledgment mode." These are the commit-level (also called accept-level) counterparts of the application codes:

  • CA โ€” Commit Accept: the message was safely received and committed to storage, but not necessarily processed by the application yet.
  • CE โ€” Commit Error: an error occurred while trying to accept the message for later processing.
  • CR โ€” Commit Reject: the message was refused at the accept stage.

The key idea is that enhanced mode separates "I have safely received and stored your message" (the C-codes) from "my application has finished processing it" (the A-codes). In original acknowledgment mode, a single ACK with AA/AE/AR covers both meanings at once. Which mode is in play is governed by fields MSH-15 and MSH-16, a topic worth understanding before you design a new interface because it changes how many acknowledgments you should expect per message.

HL7 ACK Codes Explained: AA, AE, and AR (MSA-1)

How a Receiver Decides Which Code to Send

A well-behaved receiver follows a clear decision order. First, can it accept the message at all โ€” correct type, supported version, intended for this system? If not, AR (or CR). Next, can it parse and validate the content โ€” required fields present, codes recognized, references resolvable? If not, AE (or CE), accompanied by a descriptive ERR segment. Only when both checks pass and the application has truly done its work does it return AA (or CA). Encoding this logic correctly, and pairing each negative code with an actionable error message, is what turns a fragile interface into a dependable one. When you are unsure why a partner system returned a particular code, start by inspecting the raw message structure in the HL7 viewer and confirm the MSH and MSA segments line up with what each side expects.

A Worked Example: Reading AA, AE, and AR in Raw Messages

Codes are easier to internalize against real bytes. Suppose a sending system transmits an ADT^A01 with message control ID MSG00012. A successful acknowledgment comes back like this:

MSH|^~\&|RECVAPP|RECVFAC|SENDAPP|SENDFAC|20260613103000||ACK^A01|ACK00012|P|2.5
MSA|AA|MSG00012

Notice that MSA-2 echoes the original control ID (MSG00012), letting the sender correlate the ACK with the exact message it sent. Now suppose PID-3 was blank. A well-behaved receiver returns an AE with an ERR segment that names the offending field:

MSH|^~\&|RECVAPP|RECVFAC|SENDAPP|SENDFAC|20260613103001||ACK^A01|ACK00013|P|2.5
MSA|AE|MSG00012
ERR|^^^101&Required field missing&HL70357|PID^1^3|E

Even on a negative acknowledgment, MSA-2 still echoes the original control ID (MSG00012) โ€” the new value ACK00013 in MSH-10 is the ACK's own control ID, which is separate. Finally, imagine the receiver only supports HL7 v2.3 but the sender declared 2.7 in MSH-12, or the message was an unsupported ORM type. That is a context problem, not a content one, so the right answer is AR:

MSH|^~\&|RECVAPP|RECVFAC|SENDAPP|SENDFAC|20260613103002||ACK^A01|ACK00014|P|2.5
MSA|AR|MSG00012
ERR|^^^203&Unsupported version id&HL70357|MSH^1^12|E

Paste any of these into the HL7 viewer to see each field broken out, and use the HL7 ACK generator to produce the matching ACK for a message you are testing.

Common Pitfalls That Cause Silent Data Loss

Three mistakes account for the majority of acknowledgment-related incidents in production interfaces. The first is sending AA before the application has actually committed the data. Many engines acknowledge on receipt to keep throughput high, but if downstream persistence then fails, the sender has already cleared its retry queue and the record is gone. If you cannot guarantee processing at ACK time, use enhanced mode (CA on receipt, AA after processing) so the two events are distinct.

The second is treating AE and AR identically in retry logic. Blindly retrying an AE replays the same bad content and produces an endless loop; blindly retrying an AR hammers a system that will never accept the message until its configuration changes. Route AE to a human-review queue and AR to an alert for the integration team. The third is omitting a meaningful ERR segment on negative acknowledgments. A bare MSA|AE|MSG00012 with no explanation forces analysts to guess; always include the error code, the field reference (such as PID^1^3), and a human-readable description.

A fourth, subtler pitfall is failing to echo the original message control ID in MSA-2. When the ACK does not carry back the exact control ID it is answering, the sender cannot match the acknowledgment to the message it sent, and correlation breaks down completely under load โ€” multiple in-flight messages become impossible to tell apart. Always copy MSH-10 from the inbound message into MSA-2 of the outbound ACK. Finally, remember that timeouts are a form of negative acknowledgment too: if a sender never receives any ACK within its configured window, it must treat the message as unacknowledged and follow the same review-or-retry logic, because a lost ACK and a lost message are indistinguishable from the sender's side.

Summary

HL7 ACK codes are compact but consequential. AA confirms successful application processing, AE reports a content-level error that needs correction, and AR rejects a message that the receiver should not be processing in the first place. The enhanced-mode codes CA, CE, and CR mirror these at the commit level, separating safe receipt from full processing. Map each code to the right retry behavior โ€” complete on AA, review on AE, reconfigure on AR โ€” and always pair negative acknowledgments with a clear error description. Do that, and your interfaces will fail loudly and recoverably instead of silently losing data.

← Back to Blog