ACH Dishonored Returns — Interbank Operational Disputes
Two banks enter, one return leaves 🐭 How to handle R61, R62, and other dishonored return codes in your payment system

For: Payments engineers, fintech developers, ACH operations teams
Reading Time: 12 minutes
Prerequisites: Familiarity with ACH file formats, NACHA rules, and standard return codes (R01–R33)
Why now: While dishonored returns are rare (<0.1% of all returns), they represent critical operational failures that require immediate attention. Systems without proper handling risk frozen settlements and banking partner escalations.
TL;DR:
- Dishonored returns are when the ODFI formally disputes the validity of a return sent by the RDFI.
- These are bank-to-bank operational disputes, not customer complaints.
- Primary codes: R61 (misrouted), R62 (erroneous return), R67–R69 (timing/format errors).
- Requires escalation to banking operations team and investigation workflow.
- Separate from consumer dispute processes (Reg E).
⚠️ Critical Distinction: Dishonored returns are interbank operational disputes. They are not the same as consumer disputes under Regulation E.
⚠️ Disclaimer: All scenarios, accounts, names, and data used in examples are fictional and for educational purposes only.
Problem Definition
The challenge: When your ODFI (bank partner) identifies that a return received from an RDFI is invalid, improperly formatted, or misrouted, they must formally dispute it through a dishonored return. Your system needs to recognize these scenarios and trigger appropriate operational workflows.
Who faces this: Fintechs and payment platforms that process high ACH volumes (>10,000 transactions/month) and have direct ACH sponsorship relationships.
Cost of inaction:
- Unreconciled ledger entries (funds in limbo)
- Banking partner escalations and potential fee assessments
- NACHA rule violations if a pattern emerges
- Delayed settlement for your customers
Why standard solutions fail: Most ACH integrations only handle the “happy path” return flow (debit → return → done). They don’t model the recursive case where the return itself is disputed.
Understanding Dishonored Returns
The Actual Flow
flowchart TD
A["Originator sends ACH debit"] --> B["ODFI processes debit"]
B --> C["ACH Network routes to RDFI"]
C --> D["RDFI returns transaction (R01, R03, etc.)"]
D --> E["ODFI receives return"]
E --> F{"Is return valid?"}
F -->|"Yes"| G["ODFI processes return normally"]
F -->|"No - Invalid reason or misrouted"| H["ODFI creates dishonored return entry"]
H --> I["ODFI sends dishonored return to RDFI (R61, R62, R67–R69)"]
I --> J["Banks negotiate resolution"]
J --> K["Final settlement determined"]
💡 Key Point: The ODFI is the one who dishonors (disputes) the RDFI’s return, not the other way around.
Dishonored Return Codes Explained
| Code | Official Name | What It Means | Example Scenario | Who Initiates |
|---|---|---|---|---|
| R61 | Misrouted Return | Return was sent to wrong ODFI | RDFI used old routing number; correct ODFI returns it | Correct ODFI |
| R62 | Return of Erroneous or Reversing Debit | Return itself is erroneous or reverses properly authorized debit | RDFI returned an authorized payroll debit as “unauthorized” | Original ODFI |
| R67 | Duplicate Return | Same return already processed | RDFI accidentally submitted return twice | ODFI |
| R68 | Untimely Return | Return outside allowed timeframe | Insufficient funds return sent 5 days late | ODFI |
| R69 | Field Error | Return has data format errors | Trace number missing or malformed | Either bank |
| R70 | Permissible Return Entry Not Accepted / Return Not a Duplicate | RDFI contests a dishonor | Complex dispute scenarios | RDFI |
Real-World Scenarios
Scenario 1: Misrouted Return (R61)
Situation: Acme Payroll sends a debit via ODFI Bank A (routing: 123456789). The employee changes banks, and the old RDFI returns it for “Account Closed” (R02) — but sends it to the wrong ODFI.
What happens:
- Bank A receives a return it doesn’t recognize.
- ODFI issues R61 dishonored return: “This wasn’t our transaction.”
- RDFI must reroute to the correct ODFI.
Your system’s job:
- Receive ODFI notification for R61.
- Do not adjust customer balances.
- Log for audit.
- Await correct routing.
# R61 - Misrouted Return Example
require 'date'
class ACHReturn
attr_reader :trace_number, :code, :amount_cents, :received_date
def initialize(trace_number:, code:, amount_cents:, received_date: Date.today)
@trace_number = trace_number
@code = code
@amount_cents = amount_cents
@received_date = received_date
end
end
class DishonoredReturnHandler
def handle_r61(return_item)
puts "📬 Received R61 - Misrouted return for trace #{return_item.trace_number}"
puts "⚙️ No customer impact. Logging and alerting ODFI ops."
{
status: 'dishonored',
code: return_item.code,
action: 'awaiting_correct_routing'
}
end
end
r61 = ACHReturn.new(trace_number: '000000001234567', code: 'R61', amount_cents: 150_000)
handler = DishonoredReturnHandler.new
puts handler.handle_r61(r61)
Scenario 2: Erroneous Return (R62)
Situation: Your platform processes an authorized subscription debit, but the RDFI returns it as unauthorized (R05).
What happens:
- ODFI disputes with R62 dishonored return, providing proof of authorization.
- RDFI and ODFI enter a dispute negotiation.
Your system’s job:
- Provide authorization documentation.
- Mark transaction as
under_investigation. - Set 30-day review reminder.
# R62 - Erroneous Return Example
class ErroneousReturnHandler
def initialize(odfi_client)
@odfi_client = odfi_client
end
def handle_r62(trace_number, authorization_docs)
puts "🚨 R62 - Disputing erroneous return for trace #{trace_number}"
@odfi_client.submit_dishonor_evidence(
trace_number: trace_number,
dishonor_code: 'R62',
documentation: authorization_docs
)
puts "📤 Submitted documentation to ODFI. Awaiting RDFI review."
{
status: 'under_investigation',
trace: trace_number,
action: 'evidence_submitted'
}
end
end
class MockODFIClient
def submit_dishonor_evidence(trace_number:, dishonor_code:, documentation: {})
puts "Submitting evidence for #{trace_number} with code #{dishonor_code}"
end
end
auth_docs = {
authorization_form: 'auth_form_tx001.pdf',
previous_payments: ['tx_001', 'tx_002'],
authorization_type: 'recurring_web'
}
handler = ErroneousReturnHandler.new(MockODFIClient.new)
puts handler.handle_r62('000000001234568', auth_docs)
Scenario 3: Duplicate Return (R67)
Situation: RDFI submits a duplicate return for an already processed transaction.
Your system’s job:
- Confirm duplicate caught.
- Ensure only one ledger posting.
# R67 - Duplicate Return Example
class DuplicateReturnHandler
def handle_r67(trace_number)
puts "🔁 Duplicate return detected for trace #{trace_number}."
puts "✅ ODFI rejected duplicate, verified single posting."
{
status: 'dishonored',
code: 'R67',
trace: trace_number,
action: 'duplicate_rejected'
}
end
end
handler = DuplicateReturnHandler.new
puts handler.handle_r67('000000001234569')
Monitoring & Alerts
# Example Prometheus-compatible metric logging
def record_dishonored_return(code)
puts "[METRIC] Increment counter ach_dishonored_returns_total{code=\"#{code}\"}"
end
record_dishonored_return('R62')
Prometheus Alert Rules (YAML):
groups:
- name: ach_dishonored_returns
rules:
- alert: HighR62Rate
expr: rate(ach_dishonored_returns_total{code="R62"}[1h]) > 0.01
for: 30m
labels:
severity: warning
annotations:
summary: "High R62 erroneous return rate"
description: ">1% of returns disputed as erroneous. May indicate authorization problems."
Escalation Guide
Contact your ODFI immediately if:
- R62 received without clear authorization records.
- Multiple R61s indicate routing errors.
- Unexpected R67s suggest duplicate processing.
- Investigation exceeds 10 business days — escalate through NACHA.
Validation Checklist
- ✅ System distinguishes dishonored returns (R61–R70) from standard returns.
- ✅ R61 processing avoids customer balance changes.
- ✅ R62 triggers authorization workflow.
- ✅ R67 includes duplicate detection.
- ✅ SLA tracking and alerting enabled.
- ✅ Idempotency ensured for notifications.
- ✅ Ops team escalation documented.
Takeaways
- Dishonored returns are rare but critical; handle them as exceptions.
- R62 is the highest priority — defend authorization validity.
- Never auto-process dishonored returns; route to investigation.
- Maintain close ODFI collaboration for resolution.
References
- NACHA Operating Rules & Guidelines — 2024 Rulebook
- NACHA Return Codes Reference — Official Code List, 2024
- Federal Reserve — FedACH Operating Circular, 2024
- Accuity — ACH Exception Handling Best Practices, 2023
Comments & Discussion
Share your thoughts, ask questions, or start a discussion about this article.