pain.002 Status and Reject Codes: Reading the Bank's Reply

How to read a pain.002 status report: group, payment and transaction level, the ACTC/ACCP/ACSC status codes, and reject reasons like AC01, AC04 and AM04.

On this page

A pain.002 answers your pain.001 at up to three levels โ€” the whole file, each payment batch, each transaction โ€” and every answer is a four-letter status code plus, when the status is RJCT, a reason code that tells you why. The status codes and the reason codes come from two different lists, live at different depths of the message, and are the difference between "the bank said no" and knowing at 9:05 that one supplier IBAN is dead while the other 199 salaries are fine. This is the response-side companion to the pain.001 field walkthrough: that post builds the instruction, this one decodes the reply. As there, I'll keep two sources open side by side โ€” the official ISO 20022 External Code Sets, which own the code meanings, and a real bank's pain.002 implementation guide (Nordea's, again one of the few public ones), which shows how much of the standard a bank actually sends.

Three levels of answer

The message is CustomerPaymentStatusReport โ€” root element <CstmrPmtStsRpt>. Its shape mirrors the pain.001 it answers:

  • GroupHeader <GrpHdr> โ€” the bank's own envelope: its MsgId, its CreationDateTime. Nothing about your payments yet.
  • OriginalGroupInformationAndStatus <OrgnlGrpInfAndSts> โ€” the verdict on your message: <OrgnlMsgId> echoes the MsgId of your pain.001, <OrgnlMsgNmId> names the message type it's answering, and <GrpSts> carries the group status.
  • OriginalPaymentInformationAndStatus <OrgnlPmtInfAndSts> โ€” the verdict on each batch: <OrgnlPmtInfId> echoes your PmtInfId, <PmtInfSts> carries the payment-level status. Inside it, TransactionInformationAndStatus <TxInfAndSts> answers each payment: <OrgnlInstrId> and <OrgnlEndToEndId> echo your references, <TxSts> carries the transaction status, and <StsRsnInf> carries the reason.

This is the payoff of the identifier discipline from the pain.001 side: MsgId, PmtInfId and EndToEndId each come back at exactly one level of the pain.002 โ€” Nordea's guide maps them index by index โ€” so a status finds its payment without any matching heuristics. If your EndToEndIds are lazy, this is the message where you pay for it.

An illustrative skeleton โ€” real tag names from Nordea's pain.002.001.03 guide, not a bank-ready file โ€” answering the pain.001 from the sibling post, with one transaction bounced:

XML
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03">
  <CstmrPmtStsRpt>
    <GrpHdr>
      <MsgId>BANK-STATUS-20260803-42</MsgId>
      <CreDtTm>2026-08-03T10:12:00Z</CreDtTm>
    </GrpHdr>
    <OrgnlGrpInfAndSts>
      <OrgnlMsgId>ACME-20260802-0001</OrgnlMsgId>
      <OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId>
    </OrgnlGrpInfAndSts>
    <OrgnlPmtInfAndSts>
      <OrgnlPmtInfId>ACME-20260802-0001-01</OrgnlPmtInfId>
      <PmtInfSts>PART</PmtInfSts>
      <TxInfAndSts>
        <OrgnlInstrId>INV-4711-P2P</OrgnlInstrId>
        <OrgnlEndToEndId>INV-4711</OrgnlEndToEndId>
        <TxSts>RJCT</TxSts>
        <StsRsnInf>
          <Rsn><Cd>AC04</Cd></Rsn>
          <AddtlInf>ISO Account number specified has been closed</AddtlInf>
        </StsRsnInf>
      </TxInfAndSts>
    </OrgnlPmtInfAndSts>
  </CstmrPmtStsRpt>
</Document>

One rule saves a lot of confused parsing: check the group level first. Nordea's guide states it plainly โ€” a group-level RJCT means the whole file is rejected and will not be processed, while a group-level ACTC means technical validation passed and content validation follows. If the file died at the gate, no payment- or transaction-level statuses are coming, ever, and your monitor shouldn't sit waiting for them.

The status codes: a lifecycle, not a list

The official meanings live in ISO's External Code Sets โ€” ExternalPaymentGroupStatus1Code for the group level (13 codes in the 1Q2026 edition) and ExternalPaymentTransactionStatus1Code for transactions (25 codes). In older message versions like the .03 that Nordea implements, the same codes sit as embedded schema enumerations (typed TransactionGroupStatus3Code and TransactionIndividualStatus3Code in its guide); the external list is where ISO maintains the definitions now. Read in order, the core codes are a pipeline:

CodeOfficial meaning (condensed from the ISO external code sets)
RCVDPayment initiation has been received by the receiving agent.
ACTCAuthentication and syntactical and semantical validation are successful.
ACCPPreceding check of technical validation was successful; customer profile check was also successful.
ACSPAll preceding checks such as technical validation and customer profile were successful; accepted for execution.
ACSCSettlement on the debtor's account has been completed (group set); settlement completed (transaction set).
ACCCSettlement on the creditor's account has been completed.
ACWCInstruction is accepted but a change will be made, such as date or remittance not sent.
PARTA number of transactions have been accepted, whereas another number have not yet achieved 'accepted' status.
PDNGPayment instruction is pending; further checks and status update will be performed.
RJCTPayment instruction has been rejected.

The A-codes are stages, not synonyms: ACTC says the file parsed, ACCP says the bank also recognises you, ACSP says it's going to execute, and only ACSC/ACCC talk about settlement โ€” the ISO set even flags ACSC as usable only under bilateral agreement, because settlement confirmation is what your statement is for. A payment can die after any of them. Treat every A-status short of settlement as "so far, so good", not as "done".

Three codes deserve a closer look than their four letters suggest. ACWC means the bank changed something and processed anyway โ€” date shifted past a cut-off, remittance dropped โ€” and if you file it under "accepted" without reading the change, your books and the bank's diverge silently. PART at payment level is the one that should page someone: some transactions in the batch made it, some didn't, so a blanket retry re-pays the successful ones. PDNG means the story isn't over; another pain.002 follows.

The transaction set has a longer tail โ€” ACFC (funds check passed), ACWP (accepted without posting to the creditor's account yet), BLCK (a previously-ACWP payment is now blocked in both directions), PATC (multi-authorisation flows where some approvals are still outstanding), CANC (cancelled โ€” the set marks it for API contexts), even CPUC for cash physically picked up. The newest additions are the RCVC/RVCM/RVNC family for Verification of Payee outcomes โ€” the code list is a living document, and the quarterly external-set publication is where it lives. You will not meet most of these; Nordea's guide, for instance, sends exactly two codes at group level (ACTC, RJCT) and five at payment level (ACCP, ACWC, PART, PDNG, RJCT). Same pattern as on the pain.001 side: the standard defines the vocabulary, the MIG tells you which words the bank actually speaks.

When it's RJCT: the reason codes

RJCT alone tells you nothing actionable. The why sits in <StsRsnInf> โ€” a <Rsn><Cd> holding a code from ExternalStatusReason1Code, plus optional <AddtlInf> free text. This is the list behind every "sepa reject reason code" search: 302 codes in the 1Q2026 edition (315 by 2Q2026 โ€” the full list has every one, with ISO's definition), of which a corporate treasury meets perhaps twenty-five. What follows is that curated subset with the official meanings, condensed from the ISO external code sets โ€” for anything rarer, go to the official list rather than a forum thread.

The third column in these tables is not ISO's. It is where to look first when the code comes back โ€” a starting point for the person who has to act on it, which a bank's own implementation guide outranks wherever the two differ.

Account codes โ€” the wrong-IBAN family:

CodeOfficial meaningFirst thing to check
AC01Account number is invalid or missing.The IBAN or account number in the payee record: its length and check digits. Correct the record, then issue the payment again.
AC02Debtor account number invalid or missing.Your own account in the file (the debtor account): the house-bank account this payment run is mapped to.
AC03Creditor account number invalid or missing.The beneficiary's account number as it is stored in the payee record.
AC04Account number specified has been closed on the bank of account's books.New account details from the payee โ€” through a channel you already trust, not the message that announces the change. Then update the record.
AC06Account specified is blocked, prohibiting posting of transactions against it.Nothing in your file. The account holder has to resolve the block with their bank; do not send to the same account again until they confirm.

AC01 vs AC04 is the distinction worth automating: AC01 is bad master data you can fix today; AC04 means the account existed and is gone โ€” you need a new IBAN from the beneficiary, and retrying is pointless.

Funds and amount codes:

CodeOfficial meaningFirst thing to check
AM01Specified message amount is equal to zero.Zero-amount lines in the payment run, such as items that net to nil. Leave them out before the file is built.
AM02Specific transaction/message amount is greater than allowed maximum.Which limit applies: per payment, per file or per day, set by the bank or the scheme. Split the payment or have the limit changed.
AM04Amount of funds available to cover specified message amount is insufficient.The balance of the paying account at the time of execution, and the cut-off for funding it.
AM05Duplication.Whether the earlier instruction was executed โ€” before anything is sent again.

AM04 is the insufficient-funds code โ€” on the initiation side that's your account short, which makes it a cash positioning failure wearing a format costume. AM02 usually means you tripped a limit in the bank agreement, not the scheme.

Routing and agent codes:

CodeOfficial meaningFirst thing to check
RC01Bank identifier code specified in the message has an incorrect format.The format of the BIC in the payee record: eight or eleven characters.
RC02Bank identifier is invalid or missing.Whether the BIC exists and is the one for that account's bank.
AGNTAgent in the payment workflow is incorrect.Which agent the bank means: read the additional information, then the intermediary or correspondent details in the instruction.
CNORCreditor bank is not registered under this BIC in the CSM.Whether the creditor's bank can be reached in this scheme under that BIC. If not, the payment needs another payment type, not a resend.
DNORDebtor bank is not registered under this BIC in the CSM.Your own bank's BIC in the file, and the scheme the file was sent for.

File, date and timing codes โ€” the ones test phases are made of:

CodeOfficial meaningFirst thing to check
FF01File format incomplete or invalid.The file against the bank's implementation guide: message version, mandatory elements, character set. A format fix, not a data fix.
DT01Invalid date (e.g. wrong or missing settlement date).The dates in the file: a requested execution date that is missing or not a day the bank will accept.
DT02Invalid creation date and time in Group Header (e.g. historic date).The creation date and time in the group header: a file built earlier and sent late, or a system clock.
CH03Value in Requested Execution Date is too far in the future.The requested execution date against the bank's window for future-dated payments.
CH04Value in Requested Execution Date is too far in the past.The requested execution date: usually a file that waited for approval past its date.
TM01Message, payment information block or transaction received after agreed processing cut-off time.The bank's cut-off for this payment type against the time the file arrived, not the time it was created. Then whether the bank moved it to the next day or dropped it.
DUPLPayment or charge is a duplicate of another payment or charge.Whether the first one was executed โ€” before anything is sent again.
RF01Transaction reference is not unique within the message.How references are generated: the same reference has been used twice in one message.

If the pain.001 walkthrough is the instruction manual, this table is its error page: the stale CreationDateTime, the reused MsgId, the execution date outside the window โ€” each has its own code, and each is fixable on your side without calling anyone.

When a reject traces back to the file, the fix belongs before the next send, not in this report. BankLint does not read pain.002. It validates the corrected pain.001 first: the ISO 20022 schema and, for pain.001.001.09, the SEPA Credit Transfer rules. Your bank's own rules can still reject a file that passes.

Party and regulatory codes:

CodeOfficial meaningFirst thing to check
BE01Identification of end customer is not consistent with associated account number.The payee's name in your record against the name the account is held in.
BE04Specification of creditor's address, required for payment, is missing or not correct.The creditor's address in the payee record: present, and in the form the bank requires.
MD07End customer is deceased.Not a data fix. Stop, and take it to whoever owns the relationship.
RR01Regulatory: debtor account or unique identification insufficient or missing.The debtor's account or identification in the file โ€” complete in the message, not only in the master data.
RR02Regulatory: debtor name and/or address insufficient or missing.The debtor's name and address in the file.
RR03Regulatory: creditor name and/or address insufficient or missing.The creditor's name and address in the file.
RR04Regulatory reason.Ask the bank. The code says a regulatory reason exists and nothing more; do not resend until it is explained.
AM07Amount specified in message has been blocked by regulatory authorities.Ask the bank. Nothing in the file changes it.
CURRCurrency of the payment is incorrect.The currency of the payment against what the account and the scheme accept.

BE04 and the RR-family are the structured-address era in code form: address data that used to be tolerated as missing is increasingly a hard reject.

The catch-alls โ€” where the code stops helping:

CodeOfficial meaningFirst thing to check
CUSTCancellation requested by the Debtor.Who on your own side asked for the cancellation: the debtor is the one who requested it.
MS02Reason has not been specified by end customer.The customer gave no reason. Whoever owns the relationship has to ask.
MS03Reason has not been specified by agent.The bank gave no reason. Ask it; in some countries the silence is deliberate.
NARRReason is provided as narrative information in the additional reason information.The additional information beside the code: the reason is written there.

Two of these are traps. CUST gets glossed in the wild as "customer error" or "customer decision"; the official definition in the status-reason list is narrower โ€” a cancellation the debtor asked for. And MS03 is the bank formally declining to give you a coded reason โ€” often because a sanctions or fraud screen is involved and the bank won't say so. When your reject feed is dominated by MS03 and NARR, the information you need is in <AddtlInf> or on the phone, not in the code โ€” Nordea's guide, for instance, commits to filling AdditionalInformation for every non-ACCP status, prefixing it ISO when the text comes from the external code list and CAP when it's the bank's own commentary. And banks repurpose codes too, documented in plain sight: the same guide uses MS02 with an ACWC status to signal a changed creditor account in Finland โ€” a meaning you would never derive from the official definition. When bank usage and the official list disagree, print the official meaning and read the MIG for the local dialect.

The SEPA direct debit set: MD01, MD06, AG01 and the rest

Everything above is what a credit transfer file gets back. A creditor collecting by SEPA direct debit โ€” a pain.008 โ€” meets a narrower dialect, and the European Payments Council publishes it: the reason codes its two direct debit rulebooks allow, with the kind of R-transaction each may appear in. Most are already in the tables above (AC01, AC04, AC06, AM04, AM05, CNOR, DNOR, FF01, MD07, MS02, MS03, RC01, RR01โ€“RR04). These nine are not:

CodeOfficial nameWhat the rulebook means by itArrives as
AC13Invalid Debtor Account TypeDebtor account is a consumer account. B2B collections only.Reject, return
AG01Transaction ForbiddenDirect debit forbidden on this account for regulatory reasons โ€” the EPC's example is a savings account.Reject, return
AG02Invalid Bank Operation CodeOperation code, transaction code or sequence type incorrect; invalid file format.Reject, return
BE05Unrecognised Initiating PartyIdentifier of the creditor incorrect.Reject, return
ED05Settlement FailedSettlement of the collection failed.Reject
MD01No MandateNo valid mandate (Core). No mandate, or no confirmation of it from the debtor (B2B). Unauthorised transaction, on a refund.Reject, return, refund
MD02Missing Mandatory Mandate Information In MandateMandate data missing or incorrect.Reject
MD06Refund Request By End CustomerDisputed authorised transaction. Core collections only.Refund
SL01Specific Service Offered By Debtor AgentDue to a specific service offered by the debtor's bank: creditor blocking, amount limits, frequency limits.Reject, return

Four things in the EPC's notes are worth more than the definitions.

  • MD01 and MD06 are the two refunds, on two clocks. MD06 is the unconditional refund of a Core collection, available until eight weeks after the debit date; nothing is alleged, the debtor simply asked. MD01 on a refund is the claim that the transaction was never authorised, and it runs until thirteen months after the debit date. The same code on a reject or return means something duller: no mandate on file, a B2B mandate the debtor has not yet confirmed to its bank, or a mandate the debtor's bank cancelled after 36 months without a collection.
  • AC13 is not AG01. A B2B collection presented to a consumer's account must come back as AC13; the guidance says in so many words that AG01 cannot be used for it. AG01 is the account that may not be debited at all.
  • AG02 is usually the sequence type. The use-cases the EPC lists are a recurrent collection after a one-off and a one-off after a recurrent โ€” the FRST/RCUR/OOFF/FNAL field in the pain.008 saying something the mandate's history contradicts.
  • MS03 can be a privacy rule, not a secret. The guidance reserves MS03 for countries whose law โ€” data protection, typically โ€” does not allow the debtor's bank to send AC04, AM04, MD07 or the RR codes. So a market where every failed collection is MS03 may simply be one where "insufficient funds" may not be said out loud.

And SL01 is the debtor's own hand: every consumer-invoked block โ€” this creditor, this amount, this often โ€” comes back under it. There is nothing to repair in the file. The conversation is with the customer.

A reject is not a return

One distinction keeps reconciliation honest: pain.002 RJCT happens before your money moves โ€” validation or execution failed and nothing settled. When a payment settles and then comes back (beneficiary account closed at the far end, funds recalled), that's a return, and it reaches you through your statement and reporting flow, carrying reason codes from a sibling list, ExternalReturnReason1Code. The two lists overlap heavily โ€” AC04, AM04, MD07 appear in both with essentially the same meanings โ€” but not perfectly, and the wording is set-specific: AC01 officially means "Account number is invalid or missing" as a status reason but "Format of the account number specified is not correct" as a return reason. Practical consequence: don't build one lookup table for "SEPA reject codes" and feed it both message families; key your code tables by code set, not by four letters โ€” and if you also run US ACH, the Nacha return codes are a third list again.

Misreading pain.002 status codes

  • Treating pain.002 as optional. The overview post makes this point strategically; here's the operational version: a payment run without status handling means your first reject notification is an angry supplier.
  • Waiting for transaction statuses after a group-level RJCT. The file is dead; nothing below the group level will arrive. Check <GrpSts> first.
  • Mapping every A-status to "paid". ACTC, ACCP and ACSP are checkpoints. Settlement is ACSC/ACCC at best, and your statement in practice.
  • Blanket-retrying a PART batch. Some of those payments went through. Retry the RJCT transactions by EndToEndId, or pay people twice.
  • One reason-code table for rejects and returns. Same letters, different code sets, set-specific wording. Key by set.
  • Ignoring <AddtlInf>. For MS03 and NARR it's the only content you get; for bank-specific dialects (Nordea's CAP-prefixed lines) it's where the real explanation lives.

Rejects and the statement lines they never became meet in reconciliation, and that is the step worth redesigning rather than staffing up. The bank reconciliation teardown splits it into what stays deterministic (the reason code, the amount, the reference), what an AI step can read (the free-text <AddtlInf> a bank puts beside a code), and what stays with a named human (the decision to repair, re-route or write off).

The reply side of the payment conversation is smaller than the instruction side โ€” three levels, one status vocabulary, one reason-code list โ€” but it's the half that runs at 2 a.m. when nobody's watching. Wire the codes to actions once, against the official list, and a bounced payment becomes a work item instead of an investigation.


See also the pain.001 field walkthrough, the pain.008 direct debit walkthrough, the ISO 20022 message catalogue, and the camt.053 statement walkthrough.

Three from this page

Three codes from the tables above. Pick what each one means.

Share

Primary sources

Status and reason code usage is version- and bank-specific: the official code meanings below come from the ISO 20022 External Code Sets (1Q2026 edition, which lists 302 status reason codes), and the bank behaviour follows a pain.002.001.03 implementation guide (Nordea, CGI aligned), while the ISO catalogue is at CustomerPaymentStatusReportV15. Verify which statuses and reasons your banks actually send against their own MIGs.

The code tables in this article are also in the code lookup โ€” one search box across the SAP, SWIFT MT, ISO 20022, BAI2 and NACHA ACH references.

Frequently asked questions

(5)

What is the difference between ACTC, ACCP and ACSP in pain.002?

ACTC, ACCP and ACSP are successive acceptance stages, each defined in the ISO 20022 external status code sets. ACTC means authentication and syntactical and semantical validation succeeded โ€” the file parsed and passed schema-level checks. ACCP adds that the customer profile check also passed โ€” the bank recognises the account and agreement behind the payment. ACSP means all preceding checks succeeded and the instruction has been accepted for execution. A payment can die after any of them, so none of the three means 'paid' โ€” for settlement you're waiting for ACSC or ACCC, or in practice for the account statement.

What does reject reason code AC01 mean?

In the ISO 20022 ExternalStatusReason1Code list โ€” the code set pain.002 reason codes come from โ€” AC01 officially means 'Account number is invalid or missing'. In practice it's the classic wrong-IBAN reject: the account number failed validation. One subtlety: the sibling return-reason code set defines AC01 as 'Format of the account number specified is not correct', so the same four letters carry set-specific wording depending on whether you're reading a reject or a return. Related codes: AC02 and AC03 pin the invalid account to the debtor or creditor side, and AC04 means the account has been closed.

What does MD01 mean on a SEPA direct debit?

MD01 is 'No Mandate'. On a reject or return it means there is no valid mandate for the collection โ€” none on file, a B2B mandate the debtor has not confirmed to its bank, or one the debtor's bank cancelled after 36 months without a collection. On a refund of a Core collection it is the debtor's claim that the transaction was unauthorised, which the European Payments Council's guidance allows until thirteen months after the debit date. It is different from MD06, the unconditional refund of an authorised Core collection within eight weeks.

Can a pain.002 reject a whole file?

Yes. A pain.002 can answer at group level via GroupStatus in OriginalGroupInformationAndStatus, and a group-level RJCT kills the entire original message. Nordea's pain.002 implementation guide is explicit: when it sends RJCT as the group status, the whole file is rejected and will not be processed, whereas ACTC at group level means technical validation passed and content validation continues in the back end. That's why status handling has to check the group level first โ€” if the file died there, no payment or transaction level statuses are coming.

What do MS03 and NARR mean in a payment rejection?

MS03 and NARR both come from the ISO external status reason code list and both are catch-alls. MS03 officially means 'Reason has not been specified by agent' โ€” the bank rejected the payment and is not telling you why in coded form; its sibling MS02 is the same with the end customer as the silent party. NARR means the reason is provided as narrative information in the additional reason information โ€” free text instead of a code, so your automation has to surface the AdditionalInformation element to a human. If your rejects are dominated by MS03 and NARR, the useful detail is usually in AdditionalInformation or in a phone call, not in the code.