EDI 997 Error Codes: AK304, AK403, AK501, AK901 Reference
Aug 25, 2026
Aug 25, 2026
Convert a purchase order to Excel, CSV, or JSON
Submit your purchase orders
Drop documents here, or click to file
Up to 50 files per batch
Uploading...
An EDI 997 functional acknowledgment reports whether a received interchange was syntactically valid, and nothing more. AK901 and AK501 carry the accept or reject status: A is accepted, R is rejected, P is partially accepted and E is accepted with errors noted. The reason sits in AK304 for segment level problems and AK403 for element level problems, with AK403 code 7, invalid code value, being the most common real cause. A 997 with AK901 of A does not mean the order reached anyone. It means the file parsed.
Last updated August 2026
The 997 is the first thing that comes back after you transmit an X12 document, and it is the document people most often misread. It is a syntax receipt written by a translator, not an answer from a business system. This page is the reference: every error code table in one place, the order to read the segments in, and the handful of facts that decide whether a 997 in your inbox is good news or a problem you have not noticed yet.
A 997 answers exactly one question: did the file you sent conform to the X12 syntax rules for the transaction set it claimed to be. It is generated by the receiving translator, usually within minutes, before any business application has looked at the contents.
That distinction is the whole point of the document, and it is where most confusion starts. If you send a purchase order and get back a 997 with AK901 of A, you know the envelope was well formed, the control numbers matched, and every element passed its length and type checks. You do not know that the buying system created an order. You do not know that the part numbers exist. You do not know that anybody at the supplier has seen it. The document that answers those questions is the EDI 855 purchase order acknowledgment, which comes later and carries a line by line commercial answer.
Teams that treat a clean 997 as confirmation end up with orders that were technically perfect and commercially invisible. The rule worth writing down: a 997 closes the transport question, an 855 closes the order question, and an 810 closes the money question.
A 997 is built from six AK segments wrapped in the usual ST and SE. They nest, and reading them out of order is how people end up chasing the wrong element.
| Segment | Required | What it reports | Repeats |
|---|---|---|---|
| AK1 | Mandatory | Which functional group is being acknowledged. AK101 is the original GS01 functional identifier, AK102 the group control number from GS06 and GE02. | Once |
| AK2 | Optional | Opens a loop for one transaction set inside the group. AK201 is the original ST01 (850, 855, 856) and AK202 the transaction set control number from ST02. | Once per transaction set |
| AK3 | Optional | One segment in error, located by AK301 segment ID and AK302 segment count from the ST. AK304 carries the error code. | Once per segment in error |
| AK4 | Optional | One data element in error inside the AK3 segment. AK401 gives the element position, AK403 the error code and AK404 a copy of the bad value. | Up to 99 per AK3 |
| AK5 | Mandatory in the AK2 loop | The verdict on that one transaction set. AK501 is the status, AK502 through AK506 give up to five reasons. | Once per AK2 loop |
| AK9 | Mandatory | The verdict on the whole functional group, plus the counts: AK902 sets included, AK903 received, AK904 accepted. | Once |
The nesting matters. AK4 only appears when the AK304 above it is 8, segment has data element errors. If you are hunting for an offending value and there is no AK4 anywhere in the file, the problem is not in an element at all. It is structural: a missing mandatory segment, a segment out of sequence, or a loop that repeated too many times. Look at AK304 instead.
AK901 is the headline. It is the code your monitoring should alert on, because it covers the whole functional group.
| AK901 | Meaning | What to do |
|---|---|---|
| A | Accepted | Nothing. The group parsed cleanly. Now wait for the business acknowledgment. |
| E | Accepted, but errors were noted | Read it. The data went through with complaints, and different translators disagree about when to use E, so treat it as accepted plus a warning worth reading rather than a status you can automate against. |
| P | Partially accepted, at least one transaction set was rejected | The one people miss. Some orders in the group went through and at least one did not. Alerting only on R lets these disappear. |
| R | Rejected | The entire group failed. Nothing inside it was processed. Fix and resend. |
| M | Rejected, message authentication code failed | A security failure, not a mapping one. Rarely implemented. |
| W | Rejected, assurance failed validity tests | Rarely implemented. |
| X | Rejected, content after decryption could not be analyzed | Rarely implemented. |
P is the code worth building a rule around today. A functional group can hold hundreds of transaction sets, and P means an unknown number of them were thrown away while the rest went through. A monitor that pages on R and ignores P will report a healthy channel while orders are quietly disappearing. Compare AK903, transaction sets received, against AK904, transaction sets accepted, on every 997 you take in. If those two numbers differ, something did not land, whatever AK901 says.
AK501 is the same idea one level down: the verdict on a single transaction set, meaning one purchase order, one invoice, one shipment notice.
| AK501 | Meaning |
|---|---|
| A | Accepted |
| E | Accepted but errors were noted |
| P | Partially accepted, at least one transaction set was rejected |
| R | Rejected |
| M | Rejected, message authentication code failed |
| W | Rejected, assurance failed validity tests |
| X | Rejected, content after decryption could not be analyzed |
One implementation detail that explains a lot of confusing tickets: in Microsoft BizTalk, whose EDI engine sits behind a large share of US trading relationships, none of the syntax error codes actually produce a status of E. The documentation says so directly. A transaction set is either A or R. So if you have never seen an E from a partner, that is not an oversight on their side, it is their platform. Do not build a workflow branch that waits for one.
When AK501 is R, these five optional elements say why. Up to five reasons can be given for one transaction set.
| Code | Condition | Usual cause |
|---|---|---|
| 1 | Transaction set not supported | You sent a document type the partner has not set up. A trading partner agreement problem, not a file problem. |
| 2 | Transaction set trailer missing | The SE segment did not arrive. Usually a truncated transmission. |
| 3 | Transaction set control number in header and trailer do not match | ST02 and SE02 disagree. Almost always a mapping bug that only shows up on multi document files. |
| 4 | Number of included segments does not match actual count | SE01 is wrong. A map that adds or drops a conditional segment without recounting. |
| 5 | One or more segments in error | The generic pointer. Read the AK3 and AK4 segments above for the real cause. |
| 6 | Missing or invalid transaction set identifier | ST01 is not a value the partner recognizes for that functional group. |
| 7 | Missing or invalid transaction set control number | Often a duplicate. Resending a file without incrementing ST02 triggers this. |
Code 7 deserves attention because it is usually self inflicted. When a transmission fails and somebody resends the same file unchanged, the receiving translator sees a control number it has already processed and rejects the resend as a duplicate. The order does exist on their side. Sending it a third time will not help. This is why control number sequences have to be managed by the translator and never edited by hand.
The same pattern at group level, reported in AK9 when AK901 is R.
| Code | Condition |
|---|---|
| 1 | Functional group not supported |
| 2 | Functional group version not supported |
| 3 | Functional group trailer missing |
| 4 | Group control number in the functional group header and trailer do not agree |
| 5 | Number of included transaction sets does not match actual count |
| 6 | Group control number violates syntax, and a duplicate group control number may have occurred |
Code 2, functional group version not supported, is the one that appears after an upgrade. GS08 carries the version, and a partner still mapped to 004010 will reject a 005010 group outright even though every segment inside it is perfectly formed. Version moves are a coordinated change on both sides, never a unilateral one.
AK304 is the segment level reason, reported once per segment in error in the AK3 segment.
| AK304 | Condition | What it usually means in practice |
|---|---|---|
| 1 | Unrecognized segment ID | A segment the partner does not support, or garbage produced by a bad delimiter. Check the ISA declared separators first. |
| 2 | Unexpected segment | Valid segment, wrong place. Common when a map writes an optional segment outside its loop. |
| 3 | Mandatory segment missing | The single most common structural rejection. Usually a conditional rule in the partner guide that your map treats as optional. |
| 4 | Loop occurs over maximum times | More repetitions than the guide allows, for example more N1 parties or more line items than the partner accepts in one document. |
| 5 | Segment exceeds maximum use | The same problem for a non looping segment, typically too many REF or DTM segments. |
| 6 | Segment not in defined transaction set | The segment is valid X12 but is not part of this transaction set at all. |
| 7 | Segment not in proper sequence | Right segments, wrong order. X12 segment order is fixed, not advisory. |
| 8 | Segment has data element errors | A pointer, not a cause. One or more AK4 segments follow with the real detail. |
Code 3 is worth budgeting time for on every new trading partner. X12 marks a great many segments as conditional at standard level, and each partner then makes some of them mandatory in its own implementation guide. Your map is built against the standard, their validator runs against the guide, and the gap between the two is where new relationships fail during testing.
AK403 is the element level reason, in an AK4 segment that appears only when AK304 above it is 8. AK401 tells you which element position failed and AK404 usually echoes the offending value back.
| AK403 | Condition | What it usually means in practice |
|---|---|---|
| 1 | Mandatory data element missing | An element the guide requires came through empty. Watch for source data that is null rather than absent. |
| 2 | Conditional required data element missing | A rule fired: because element X was populated, element Y became required. The hardest class to catch in testing. |
| 3 | Too many data elements | The segment has more elements than the standard defines, usually from an unescaped separator inside a value. |
| 4 | Data element is too short | Below the minimum length. Zero padded IDs that lost their padding are the classic case. |
| 5 | Data element is too long | Above the maximum length. Long descriptions and long addresses overflow quietly. |
| 6 | Invalid character in data element | A character outside the allowed character set, often a smart quote, an accent or a delimiter that appears inside a value. |
| 7 | Invalid code value | The most common rejection of all. A qualifier or code that is not in the partner accepted list. |
| 8 | Invalid date | A date that is not valid, or a CCYYMMDD field carrying a YYMMDD value after a version change. |
| 9 | Invalid time | Same class of problem in an HHMM or HHMMSS field. |
| 10 | Exclusion condition violated | Two elements were populated that the guide says are mutually exclusive. |
If you only memorize one code from this page, memorize 7. Invalid code value covers unit of measure qualifiers, party identification qualifiers, product ID qualifiers, date and reference qualifiers, and every other place where X12 uses a two or three character code from a list. Every partner trims those lists in its own guide. Sending EA for each to a partner that only accepts CA and PC is a perfectly valid X12 file and a rejected order.
Work outside in, not top down. The file below rejects one transaction set inside an otherwise healthy group.
ST*997*0001~
AK1*PO*000000123~
AK2*850*0002~
AK3*PO1*7**8~
AK4*3**7*ZZ~
AK5*R*5~
AK9*P*3*3*2~
SE*8*0001~Read it in this order:
AK9 first. AK901 is P, so the group was partially accepted. AK902, AK903 and AK904 say three transaction sets were included, three received and only two accepted. One order was lost, and a monitor watching only for R would have called this a success.
AK1 next to identify what was acknowledged: functional identifier PO, group control number 000000123. That is the GS06 you sent, and it is how you find the original file.
AK2 next. Transaction set 850, control number 0002. Now you know precisely which purchase order failed, because 0002 is the ST02 of the second order in your file.
AK5 next. AK501 is R, rejected, and AK502 is 5, one or more segments in error. That is a pointer telling you to keep reading upward, not a cause.
AK3 and AK4 last, and together. AK301 says the failing segment is PO1 and AK302 says it is segment 7 counting from the ST. AK304 is 8, so the problem is inside an element and an AK4 follows. AK401 is 3, the third element of PO1, which is the unit of measure. AK403 is 7, invalid code value, and AK404 echoes back ZZ. The order was rejected because it asked for a unit of measure the partner does not accept. Fix the map, increment the control number, resend.
The 999 implementation acknowledgment replaced the 997 in US healthcare under HIPAA 5010, effective March 2012. The 997 reports conformance to the X12 standard; the 999 additionally reports conformance to the HIPAA implementation guide, which is a stricter test. Structurally the 999 uses IK3, IK4 and IK5 segments where the 997 uses AK3, AK4 and AK5, and it adds a CTX context segment that names the data which triggered a situational rule.
For supply chain EDI, meaning 850, 855, 856 and 810 traffic, the 997 remains the acknowledgment in normal use. You will only meet a 999 if you also exchange healthcare claims. The two can coexist: the standard allows partners to agree that some functional groups in an interchange are acknowledged with a 997 and others with a 999.
Neither one should be confused with a TA1, which acknowledges the interchange envelope itself rather than the functional groups inside it. If your ISA or IEA is malformed, no 997 can be produced at all, because the translator cannot get far enough into the file to find a functional group. A TA1 is what comes back instead, and a silence where you expected a 997 is often a TA1 you are not capturing.
No. A 997 with AK901 of A means the file was syntactically valid and was passed to the receiving system. It says nothing about whether an order was created, whether the items exist, whether pricing was agreed or whether anything will ship. The commercial answer arrives in the 855 purchase order acknowledgment, and the goods movement in the 856.
You break a contractual obligation in most trading partner agreements, and you leave the sender unable to distinguish a delivered file from a lost one. Retail and automotive programs commonly require a 997 within a defined window, often one business day, and repeated failures can carry chargebacks. Sending acknowledgments is not optional courtesy in those programs.
Because nothing was wrong, or because your partner only reports rejections. Many translators are configured to emit the AK2 loop only for rejected transaction sets, so a clean group produces AK1, AK5 and AK9 and nothing else. In BizTalk this is a checkbox for including the AK2 loop for accepted transaction sets, off by default. A short 997 is usually the best kind.
Minutes, not hours, because it is produced by the translator on receipt rather than by a business process. Trading partner agreements typically allow a window of one business day, but in practice a 997 that has not arrived within an hour on an established connection is a transport problem worth investigating rather than a slow response. Modern connections run over AS2 endpoints or HTTPS APIs rather than a dial up VAN mailbox, so if acknowledgments stop arriving the first thing to rule out is that the endpoint receiving them is actually up, which is the kind of check a scheduled monitor on the endpoint answers faster than a partner ticket does.
It can be syntactically invalid, but by convention a 997 is not acknowledged with another 997. Doing so would create an infinite acknowledgment loop, so translators are configured not to acknowledge acknowledgments. If a partner reports that your 997 is unreadable, they will tell you out of band.
| Fact | Why it matters |
|---|---|
| AK901 of A is a syntax pass, not an order | The most expensive misreading in EDI operations. Nothing about the business transaction is confirmed until the 855 arrives. |
| P is as serious as R | Partial acceptance means silent partial loss. Alert on P and on any file where AK904 is less than AK903. |
| AK4 exists only when AK304 is 8 | No AK4 means the problem is structural, not a bad value. Stop hunting for the offending element. |
| E may never appear at all | Some major platforms never emit E. Do not write a branch that waits for it. |
| No 997 at all is a different failure | A malformed ISA or IEA produces a TA1, not a 997. Silence usually means the interchange never got parsed, not that it is still being processed. |
The 997 is the receipt, not the reply. In a normal supply chain exchange the buyer sends an EDI 850 purchase order, the supplier translator returns a 997 within minutes, the supplier business system returns an 855 purchase order acknowledgment with the line by line answer, and an EDI 856 advance ship notice follows when the goods move. Each one answers a different question and none of them substitutes for another. The purchase order acknowledgment process covers what to do with the exceptions once you can see them, and cXML vs EDI explains why some large buyers run a completely different protocol with a different acknowledgment model.
One practical note for anyone supporting both channels. Most suppliers and most buying desks do not run EDI with every trading partner, and the orders and confirmations that arrive as PDFs get no acknowledgment of any kind, in either direction. There is no AK901 for an emailed order. EDI vs PDF purchase orders covers when the setup is worth it, and if the document channel is where your volume actually is, extracting those purchase orders to Excel or straight into an ERP import is what closes the same gap without a VAN.
Stop retyping purchase orders
Upload a PDF, scan, or photo of any PO and get clean Excel, CSV, or JSON line items in seconds.
Try it free25 pages free. No credit card required.