Kolos Hetyéssy Software developer

Free tools / SEPA & NACHA Payment File API

ACH return codes (R01–R85) and change codes (C01–C14) explained

A payment came back with R03 or a C02 change notice? The tables below explain every code and what to do next. The last sample tab shows a real return file and the API's answer for it.

  • Free, no sign-up
  • Your file is never stored
  • Deterministic: no AI guesswork

Try it now

The last sample is a return file; open its second JSON answer to see the returns explained. The live demo validates NACHA files; explaining returns is an API call. Please do not upload a real file with real account numbers.

The live demo needs JavaScript, which seems to be switched off. The sample tabs show the engine's real output without it.

A PPD payroll file (three credits) generated by the API from a three-line CSV. Every check passes. Names, accounts and routing numbers are made up.

ach-ppd-payroll.ach 950 bytes · NACHA PPD

Input file

101 07400001012345678902610210900A094101SAMPLE BANK            ACME PAYROLL INC               
5220ACME PAYROLL                        1234567890PPDPAYROLL         261023   1074000010000001
6221210003584400123456       0000185000               MARIA LOPEZ             1074000010000001
705OCTOBER SALARY                                                                  00010000001
63202200006277-1290          0000231045               SAM O'BRIEN             1074000010000002
705OCTOBER SALARY                                                                  00010000002
6220610001599100022          0000167520               LEE CHEN                0074000010000003
822000000500204000560000000000000000005835651234567890                         074000010000001
9000001000001000000050020400056000000000000000000583565                                       
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

Validation result

VALID 0 errors · 0 warnings

ACME PAYROLL INC
2026-10-21
Batches · entries
1 · 3
Total debit
0.00 USD
Total credit
5835.65 USD

No problems found. Record lengths, routing check digits, trace numbers, entry hash, totals and block count all pass.

JSON response POST /v1/ach/validate
{
  "format": "nacha",
  "valid": true,
  "error_count": 0,
  "warning_count": 0,
  "summary": {
    "immediate_destination": "074000010",
    "immediate_destination_name": "SAMPLE BANK",
    "immediate_origin": "1234567890",
    "immediate_origin_name": "ACME PAYROLL INC",
    "file_creation_date": "2026-10-21",
    "file_id_modifier": "A",
    "batches": 1,
    "entries": 3,
    "addenda": 2,
    "returns": 0,
    "notifications_of_change": 0,
    "total_debit": "0.00",
    "total_credit": "5835.65",
    "balanced": false,
    "sec_codes": [
      "PPD"
    ],
    "lines": 10
  },
  "issues": []
}

A PPD debit file written by an independent ACH library. Structure and totals pass; two lines without their trailing spaces and the old effective date are reported as warnings. Test file from the open-source Moov ACH project (Apache-2.0), unmodified.

ach-ppd-debit-moov.ach 891 bytes · NACHA PPD

Input file

101 23138010401210428821906240000A094101Federal Reserve Bank   My Bank Name
5225Name on Account                     121042882 PPDREG.SALARY      190625   1121042880000001
62723138010412345678         0100000000               Receiver Account Name   0121042880000001
82250000010023138010000100000000000000000000121042882                          121042880000001
9000001000001000000010023138010000100000000000000000000
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

Validation result

VALID 0 errors · 3 warnings

My Bank Name
2019-06-24
Batches · entries
1 · 1
Total debit
1000000.00 USD
Total credit
0.00 USD

WARNING · RECORD_LENGTH line 1 The line has 75 characters instead of 94; trailing spaces seem to be missing. Many banks reject such files.

WARNING · EFFECTIVE_DATE_PAST line 2, col 70-75 The effective date 2019-06-25 is in the past; the ACH operator will settle on the next possible banking day.

WARNING · RECORD_LENGTH line 5 The line has 55 characters instead of 94; trailing spaces seem to be missing. Many banks reject such files.

JSON response POST /v1/ach/validate
{
  "format": "nacha",
  "valid": true,
  "error_count": 0,
  "warning_count": 3,
  "summary": {
    "immediate_destination": "231380104",
    "immediate_destination_name": "Federal Reserve Bank",
    "immediate_origin": "0121042882",
    "immediate_origin_name": "My Bank Name",
    "file_creation_date": "2019-06-24",
    "file_id_modifier": "A",
    "batches": 1,
    "entries": 1,
    "addenda": 0,
    "returns": 0,
    "notifications_of_change": 0,
    "total_debit": "1000000.00",
    "total_credit": "0.00",
    "balanced": false,
    "sec_codes": [
      "PPD"
    ],
    "lines": 10
  },
  "issues": [
    {
      "severity": "warning",
      "rule": "RECORD_LENGTH",
      "line": 1,
      "found": 75,
      "message": "The line has 75 characters instead of 94; trailing spaces seem to be missing. Many banks reject such files."
    },
    {
      "severity": "warning",
      "rule": "EFFECTIVE_DATE_PAST",
      "line": 2,
      "field": "effective_entry_date",
      "column": "70-75",
      "found": "190625",
      "message": "The effective date 2019-06-25 is in the past; the ACH operator will settle on the next possible banking day."
    },
    {
      "severity": "warning",
      "rule": "RECORD_LENGTH",
      "line": 5,
      "found": 55,
      "message": "The line has 55 characters instead of 94; trailing spaces seem to be missing. Many banks reject such files."
    }
  ]
}

The same kind of file with a wrong routing check digit in the entry: the receiving bank would return it (R28). Test file from the open-source Moov ACH project (Apache-2.0), unmodified.

ach-ppd-wrong-check-digit-moov.ach 891 bytes · NACHA PPD

Input file

101 23138010401210428821906240000A094101Federal Reserve Bank   My Bank Name
5225Name on Account                     121042882 PPDREG.SALARY      190625   1121042880000001
62723138010512345678         0100000000               Receiver Account Name   0121042880000001
82250000010023138010000100000000000000000000121042882                          121042880000001
9000001000001000000010023138010000100000000000000000000
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

Validation result

INVALID 1 error · 3 warnings

My Bank Name
2019-06-24
Batches · entries
1 · 1
Total debit
1000000.00 USD
Total credit
0.00 USD

WARNING · RECORD_LENGTH line 1 The line has 75 characters instead of 94; trailing spaces seem to be missing. Many banks reject such files.

WARNING · EFFECTIVE_DATE_PAST line 2, col 70-75 The effective date 2019-06-25 is in the past; the ACH operator will settle on the next possible banking day.

ERROR · ROUTING_CHECK_DIGIT line 3, col 12 231380105 is not a valid routing number: with these first 8 digits the check digit would be 4.

WARNING · RECORD_LENGTH line 5 The line has 55 characters instead of 94; trailing spaces seem to be missing. Many banks reject such files.

JSON response POST /v1/ach/validate
{
  "format": "nacha",
  "valid": false,
  "error_count": 1,
  "warning_count": 3,
  "summary": {
    "immediate_destination": "231380104",
    "immediate_destination_name": "Federal Reserve Bank",
    "immediate_origin": "0121042882",
    "immediate_origin_name": "My Bank Name",
    "file_creation_date": "2019-06-24",
    "file_id_modifier": "A",
    "batches": 1,
    "entries": 1,
    "addenda": 0,
    "returns": 0,
    "notifications_of_change": 0,
    "total_debit": "1000000.00",
    "total_credit": "0.00",
    "balanced": false,
    "sec_codes": [
      "PPD"
    ],
    "lines": 10
  },
  "issues": [
    {
      "severity": "warning",
      "rule": "RECORD_LENGTH",
      "line": 1,
      "found": 75,
      "message": "The line has 75 characters instead of 94; trailing spaces seem to be missing. Many banks reject such files."
    },
    {
      "severity": "warning",
      "rule": "EFFECTIVE_DATE_PAST",
      "line": 2,
      "field": "effective_entry_date",
      "column": "70-75",
      "found": "190625",
      "message": "The effective date 2019-06-25 is in the past; the ACH operator will settle on the next possible banking day."
    },
    {
      "severity": "error",
      "rule": "ROUTING_CHECK_DIGIT",
      "line": 3,
      "field": "check_digit",
      "column": "12",
      "found": "5",
      "expected": "4",
      "message": "231380105 is not a valid routing number: with these first 8 digits the check digit would be 4."
    },
    {
      "severity": "warning",
      "rule": "RECORD_LENGTH",
      "line": 5,
      "found": 55,
      "message": "The line has 55 characters instead of 94; trailing spaces seem to be missing. Many banks reject such files."
    }
  ]
}

A file of returned WEB debits, as a bank sends it back. The API's returns endpoint lists each return with its code explained. Test file from the open-source Moov ACH project (Apache-2.0), unmodified.

ach-return-web-moov.ach 949 bytes · NACHA WEB

Input file

101 091400606 6910001341810170306A094101FIRST BANK & TRUST     ASF APPLICATION SUPERVI        
5200CoinLion                            123456789 WEBTRANSFER        000101   1091000010000001
626091400606123456789        0000012354MjMxNDAwMjAtOGQPaul Jones            S 1091000017611242
799R01091400600000001      09100001                                            091000017611242
82000000020009140060000000012354000000000000 123456789                         091000010000001
5200CoinLion                            123456789 WEBTRANSFER        000101   1021000020000002
621091400606867530999999     0000004565NmRjZTJmMzItMGNBob Marley            S 1021000029461242
799R03091400600000003      02100002                                            021000029461242
82000000020009140060000000000000000000004565 123456789                         021000020000002
9000002000001000000040018280120000000012354000000004565                                       

Validation result

VALID 0 errors · 3 warnings

ASF APPLICATION SUPERVI
2018-10-17
Batches · entries
2 · 2
Returns · changes
2 · 0
Total debit
123.54 USD
Total credit
45.65 USD

WARNING · EFFECTIVE_DATE_PAST line 2, col 70-75 The effective date 2000-01-01 is in the past; the ACH operator will settle on the next possible banking day.

WARNING · PURCHASE_DESCRIPTION line 2, col 54-63 Since 2026-03-20 WEB debits for online purchases of goods must use the description PURCHASE. Ignore this if these debits are not purchases (e.g. subscriptions or bills).

INFO · SERVICE_CLASS_200 line 2, col 2-4 Mixed service class 200 with debits only; some banks expect 225.

WARNING · EFFECTIVE_DATE_PAST line 6, col 70-75 The effective date 2000-01-01 is in the past; the ACH operator will settle on the next possible banking day.

INFO · SERVICE_CLASS_200 line 6, col 2-4 Mixed service class 200 with credits only; some banks expect 220.

JSON response POST /v1/ach/validate
{
  "format": "nacha",
  "valid": true,
  "error_count": 0,
  "warning_count": 3,
  "summary": {
    "immediate_destination": "091400606",
    "immediate_destination_name": "FIRST BANK & TRUST",
    "immediate_origin": "691000134",
    "immediate_origin_name": "ASF APPLICATION SUPERVI",
    "file_creation_date": "2018-10-17",
    "file_id_modifier": "A",
    "batches": 2,
    "entries": 2,
    "addenda": 2,
    "returns": 2,
    "notifications_of_change": 0,
    "total_debit": "123.54",
    "total_credit": "45.65",
    "balanced": false,
    "sec_codes": [
      "WEB"
    ],
    "lines": 10
  },
  "issues": [
    {
      "severity": "warning",
      "rule": "EFFECTIVE_DATE_PAST",
      "line": 2,
      "field": "effective_entry_date",
      "column": "70-75",
      "found": "000101",
      "message": "The effective date 2000-01-01 is in the past; the ACH operator will settle on the next possible banking day."
    },
    {
      "severity": "warning",
      "rule": "PURCHASE_DESCRIPTION",
      "line": 2,
      "field": "company_entry_description",
      "column": "54-63",
      "found": "TRANSFER",
      "expected": "PURCHASE",
      "message": "Since 2026-03-20 WEB debits for online purchases of goods must use the description PURCHASE. Ignore this if these debits are not purchases (e.g. subscriptions or bills)."
    },
    {
      "severity": "info",
      "rule": "SERVICE_CLASS_200",
      "line": 2,
      "field": "service_class_code",
      "column": "2-4",
      "found": "200",
      "message": "Mixed service class 200 with debits only; some banks expect 225."
    },
    {
      "severity": "warning",
      "rule": "EFFECTIVE_DATE_PAST",
      "line": 6,
      "field": "effective_entry_date",
      "column": "70-75",
      "found": "000101",
      "message": "The effective date 2000-01-01 is in the past; the ACH operator will settle on the next possible banking day."
    },
    {
      "severity": "info",
      "rule": "SERVICE_CLASS_200",
      "line": 6,
      "field": "service_class_code",
      "column": "2-4",
      "found": "200",
      "message": "Mixed service class 200 with credits only; some banks expect 220."
    }
  ]
}
JSON response POST /v1/ach/returns
{
  "returns": 2,
  "notifications_of_change": 0,
  "other_entries": 0,
  "returned_amount": "169.19",
  "by_code": {
    "R01": 1,
    "R03": 1
  },
  "items": [
    {
      "kind": "return",
      "code": "R01",
      "title": "Insufficient funds",
      "explanation": "The account did not have enough money for the debit.",
      "action": "You may try again up to two more times within 180 days of the original effective date.",
      "retry_allowed": true,
      "original_trace_number": "091400600000001",
      "original_rdfi": "09100001",
      "date_of_death": null,
      "addenda_information": "",
      "addenda_line": 4,
      "entry": {
        "batch": 1,
        "line": 3,
        "sec_code": "WEB",
        "company_name": "CoinLion",
        "company_identification": "123456789",
        "description": "TRANSFER",
        "effective_date": "2000-01-01",
        "transaction_code": "26",
        "type": "debit",
        "account_type": "checking",
        "prenote": false,
        "routing": "091400606",
        "account": "123456789",
        "amount": "123.54",
        "name": "Paul Jones",
        "identification_number": "MjMxNDAwMjAtOGQ",
        "trace_number": "091000017611242"
      }
    },
    {
      "kind": "return",
      "code": "R03",
      "title": "No account / unable to locate account",
      "explanation": "The account number does not exist at this bank, or does not match the name.",
      "action": "Check the account number and routing number with the receiver.",
      "retry_allowed": false,
      "original_trace_number": "091400600000003",
      "original_rdfi": "02100002",
      "date_of_death": null,
      "addenda_information": "",
      "addenda_line": 8,
      "entry": {
        "batch": 2,
        "line": 7,
        "sec_code": "WEB",
        "company_name": "CoinLion",
        "company_identification": "123456789",
        "description": "TRANSFER",
        "effective_date": "2000-01-01",
        "transaction_code": "21",
        "type": "credit",
        "account_type": "checking",
        "prenote": false,
        "routing": "091400606",
        "account": "867530999999",
        "amount": "45.65",
        "name": "Bob Marley",
        "identification_number": "NmRjZTJmMzItMGN",
        "trace_number": "021000029461242"
      }
    }
  ],
  "note": "Explanations are our own summaries, not the text of the Nacha Operating Rules."
}

How it works

  1. Get the return or notification-of-change file from your bank. Returns carry an addenda record of type 99, change notices one of type 98.
  2. Send it to the API’s POST /v1/ach/returns.
  3. You get one item per return or change: the code, its meaning, what to do, whether a retry is allowed, the corrected data and the original entry.

All codes

Return codes

Code Meaning What to do
R01 Insufficient funds: The account did not have enough money for the debit. You may try again up to two more times within 180 days of the original effective date.
R02 Account closed: The account was closed before the entry arrived. Ask the receiver for a new account; do not send again to this one.
R03 No account / unable to locate account: The account number does not exist at this bank, or does not match the name. Check the account number and routing number with the receiver.
R04 Invalid account number structure: The account number has the wrong format for this bank. Check the account number with the receiver.
R05 Unauthorized debit to consumer account using corporate SEC code: A CCD or CTX debit went to a consumer account without the consumer’s authorization. Use PPD/WEB/TEL with a consumer authorization, or stop debiting.
R06 Returned per ODFI’s request: Your own bank asked for this entry back. Ask your bank why.
R07 Authorization revoked by customer: The consumer withdrew the authorization for these debits. Stop debiting until you have a new authorization.
R08 Payment stopped: The receiver asked their bank to stop this payment. Contact the receiver; do not resend without agreement.
R09 Uncollected funds: There was money in the account, but not yet available. You may try again up to two more times within 180 days of the original effective date.
R10 Customer advises originator is not known or not authorized: The account holder says they do not know you or did not authorize this debit. Stop debiting; get a valid authorization first. Unauthorized returns count toward the network’s return-rate limits.
R11 Customer advises entry not in accordance with the terms of the authorization: The debit differs from what was authorized (amount, date, or other terms). Fix the error; a corrected entry may be sent within 60 days of the settlement date of the return.
R12 Account sold to another DFI: The account moved to a different bank. Ask the receiver for the new routing and account number.
R13 Invalid ACH routing number: The routing number is not a valid ACH participant. Check the routing number.
R14 Representative payee deceased or unable to continue: The representative payee died or can no longer act. Stop the payments and contact the beneficiary’s representative.
R15 Beneficiary or account holder deceased: The account holder has died. Stop the payments. The date of death may be in the return addenda.
R16 Account frozen / entry returned per OFAC instruction: The account is frozen, or the entry was returned under a sanctions instruction. Do not resend; contact the receiver.
R17 File record edit criteria / questionable entry: A field could not be processed, or the bank considered the entry suspicious. Check the entry fields; if fraud is suspected, investigate.
R18 Improper effective entry date: The effective date was not acceptable. Fix the date and resend.
R19 Amount field error: The amount is invalid (for example zero, or not zero for a prenote). Fix the amount and resend.
R20 Non-transaction account: The account does not allow this kind of transaction. Ask the receiver for a different account.
R21 Invalid company identification: The receiver’s bank did not accept the company identification. Check the company identification in the batch header.
R22 Invalid individual ID number: The receiver’s bank did not accept the individual ID number. Check the identification number of the entry.
R23 Credit entry refused by receiver: The receiver refused the credit. Contact the receiver.
R24 Duplicate entry: The receiver’s bank believes this entry was already sent. Check whether you sent it twice before resending.
R25 Addenda error: The addenda record was wrong or missing. Fix the addenda and resend.
R26 Mandatory field error: A required field was missing or wrong. Fix the entry and resend.
R27 Trace number error: The trace number of the original entry was wrong. Check the trace numbers.
R28 Routing number check digit error: The check digit of the routing number is wrong. Fix the routing number.
R29 Corporate customer advises not authorized: The business account holder says this debit was not authorized. Stop debiting; get a valid authorization first.
R30 RDFI not participant in check truncation program Contact your bank.
R31 Permissible return entry (CCD and CTX only): The receiver’s bank returned the entry late, with your agreement. None, if you agreed.
R32 RDFI non-settlement: The receiver’s bank could not settle the entry. Contact your bank.
R33 Return of XCK entry Contact your bank.
R34 Limited participation DFI: The receiver’s bank may not receive this kind of entry. Use a different account or payment method.
R35 Return of improper debit entry: Debits are not allowed for this SEC code or account. Use the right SEC code.
R36 Return of improper credit entry: Credits are not allowed for this SEC code. Use the right SEC code.
R37 Source document presented for payment: The check was also presented as a paper item. Do not collect twice.
R38 Stop payment on source document Contact the receiver.
R39 Improper source document / source document presented for payment Contact your bank.
R40 Return of ENR entry by federal government agency Fix the enrollment.
R41 Invalid transaction code (ENR) Fix the enrollment.
R42 Routing number / check digit error (ENR) Fix the enrollment.
R43 Invalid DFI account number (ENR) Fix the enrollment.
R44 Invalid individual ID number / identification number (ENR) Fix the enrollment.
R45 Invalid individual name / company name (ENR) Fix the enrollment.
R46 Invalid representative payee indicator (ENR) Fix the enrollment.
R47 Duplicate enrollment None.
R50 State law affecting RCK acceptance Contact your bank.
R51 Item related to RCK entry is ineligible or RCK entry is improper Contact your bank.
R52 Stop payment on item related to RCK entry Contact the receiver.
R53 Item and RCK entry presented for payment Do not collect twice.
R61 Misrouted return: A return was sent to the wrong bank. Contact your bank.
R62 Return of erroneous or reversing debit Contact your bank.
R67 Duplicate return: The return was sent twice. Contact your bank.
R68 Untimely return: The return was sent after the deadline. Contact your bank.
R69 Field error(s): The return had wrong fields. Contact your bank.
R70 Permissible return entry not accepted / return not requested by ODFI Contact your bank.
R71 Misrouted dishonored return Contact your bank.
R72 Untimely dishonored return Contact your bank.
R73 Timely original return Contact your bank.
R74 Corrected return Contact your bank.
R75 Return not a duplicate Contact your bank.
R76 No errors found Contact your bank.
R77 Non-acceptance of R62 dishonored return Contact your bank.
R80 IAT entry coding error Fix the IAT entry.
R81 Non-participant in IAT program Use a different payment method.
R82 Invalid foreign receiving DFI identification Fix the foreign bank identification.
R83 Foreign receiving DFI unable to settle Contact your bank.
R84 Entry not processed by gateway Contact your bank.
R85 Incorrectly coded outbound international payment: The payment should have been sent as IAT. Resend as IAT.

Change codes (notifications of change)

Update your records with the corrected data before the next entry to this account (the rules give at least six banking days). The entry itself was posted.

Code Meaning Corrected data
C01 Incorrect account number account number
C02 Incorrect routing number routing number
C03 Incorrect routing number and account number routing number, account number
C04 Incorrect individual name / receiving company name name
C05 Incorrect transaction code transaction code
C06 Incorrect account number and transaction code account number, transaction code
C07 Incorrect routing number, account number and transaction code routing number, account number, transaction code
C08 Incorrect receiving DFI identification (IAT only) rdfi identification
C09 Incorrect individual identification number identification number
C10 Incorrect company name company name
C11 Incorrect company identification company identification
C12 Incorrect company name and company identification company name, company identification
C13 Addenda format error –
C14 Incorrect SEC code for outbound international payment sec code

The API’s answer for one return, from the sample file:

{
  "kind": "return",
  "code": "R01",
  "title": "Insufficient funds",
  "explanation": "The account did not have enough money for the debit.",
  "action": "You may try again up to two more times within 180 days of the original effective date.",
  "retry_allowed": true,
  "original_trace_number": "091400600000001"
}

The same codes are available as JSON from GET /v1/ach/codes (live on RapidAPI). Sample files marked “Moov” are unmodified test files from the open-source Moov ACH project (Apache License 2.0). Not affiliated with Nacha.

Questions

What is the difference between a return and a notification of change?

A return (R code) means the entry was not posted and the money comes back. A notification of change (C code) means the entry was posted, but some account data was wrong; you must correct it before the next entry to that account.

Which returns may be sent again?

R01 (insufficient funds) and R09 (uncollected funds): up to two more times within 180 days of the original effective date. Other returns need a fix or a new authorization first.

Where does the explanation come from?

From our own summaries. They follow the public code lists, not the text of the Nacha Operating Rules. This tool is not affiliated with Nacha; for binding wording, see the rules or ask your bank.

Is my file stored?

No. It is processed in memory and discarded right after the answer is sent back. See the privacy notice.

Need it in your own software?

The same engine is available as an API: whole files instead of a preview, every export format, automation.

SEPA & NACHA Payment File API →

Related tools

Free toolSEPA & NACHA Payment File API

pain.001 validator

Check a pain.001 or pain.008 file against the ISO 20022 schema and the EPC rules, with every problem explained.

Free toolSEPA & NACHA Payment File API

pain.001.001.03 to .09

Migrate 2009 SEPA files to the 2019 versions, checked against the new schema and the SEPA rules.

Free toolSEPA & NACHA Payment File API

NACHA file validator

Check a NACHA ACH file record by record, with each problem's line, column and a plain explanation.