Fiscalapi
How to replace a CFDI issued with errors

How to replace a CFDI issued with errors

July 19, 2026

Leer en español

You issued an invoice with the wrong RFC (Mexico's taxpayer ID, Registro Federal de Contribuyentes), a miscalculated amount, or the wrong SAT product or service key. The SAT (Mexico's tax authority, Servicio de Administración Tributaria) doesn't let you edit a stamped CFDI (CFDI: Mexico's electronic invoice; stamping: the certification by a SAT-authorized provider that makes a CFDI valid), not even a comma. The only way out is to replace a CFDI the way the SAT allows: a CFDI replacement (you issue a corrected CFDI related to the original with relationship type 04, then cancel the original with reason 01). When you cancel, you state that the original was replaced. Sounds simple. In practice, the order of operations and a couple of fields filled in wrong turn this 5-minute task into an invoice you can't cancel.

What is CFDI substitution

CFDI substitution, or CFDI replacement, is the SAT procedure for replacing a stamped invoice that contains errors. You issue a new CFDI that points to the original as its related CFDI (a CFDI this one replaces, credits, or pays, with its TipoRelacion key) through relationship type 04. Then you cancel the original. The cancellation reason (one of the SAT keys 01 to 04) is 01 (issued with errors, replaced by a related CFDI), and the request carries the UUID (folio fiscal, the unique ID the PAC assigns when it stamps a CFDI) of the CFDI that replaces it.

The result: the original CFDI is canceled, the new one is active (vigente: not canceled with the SAT), and the SAT has an explicit trail showing that one replaced the other. That trail is what protects your customer's deduction and keeps the income from being counted twice in your tax returns.

When to replace an invoice and when canceling is enough

Not every error calls for a replacement. The decision depends on whether the transaction happened and whether there will be a replacement CFDI:

SituationWhat to doCancellation reason
Invoice with errors (RFC, amounts, keys) and the transaction did happenReplace: issue a new CFDI and cancel the original01, related to the replacement
Invoice with errors, but there won't be a replacementCancel only02, no relationship
The transaction never took placeCancel only03
A sale invoiced in the customer's own name that was already in a global invoice (factura global, one CFDI that groups a period's sales to the general public)Cancel the related global invoice04

The classic mix-up: cancellation reason 01 and relationship type 04 work as a pair, but they belong to different catalogs. 04 goes in the new CFDI (the TipoRelacion field). 01 goes in the cancellation request for the old CFDI. For details on every relationship type, the full catalog is in the CFDI relationship types guide.

How to replace a CFDI with the SAT, step by step

The order is the part most people get wrong. First you issue the replacement, then you cancel the original. Never the other way around.

1

Issue the replacement CFDI with relationship type 04#

Generate the corrected invoice. In the CfdiRelacionados node, set TipoRelacion = 04 (Sustitución de los CFDI previos, replacement of previous CFDIs) and add the UUID of the original CFDI. Without this node, the new CFDI has no link at all to the one it's meant to replace.

2

Save the UUID of the replacement#

When the PAC (Proveedor Autorizado de Certificación, a SAT-authorized provider that stamps CFDIs) stamps the new CFDI, it assigns the CFDI its own UUID. You need it in the next step: a cancellation with reason 01 requires it.

3

Cancel the original CFDI with cancellation reason 01#

Request the cancellation of the old CFDI with reason 01 (Comprobante emitido con errores con relación, issued with errors, replaced by a related CFDI) and put the UUID of the replacement in the replacement UUID field. It has to be the UUID of the CFDI that relates the original with type 04.

4

Check the status of both CFDIs#

The original must end up canceled, or waiting for cancellation acceptance (the recipient's approval that some cancellations require before they take effect), and the replacement must be active. If the recipient rejects the cancellation, the process is left half done and you have two live CFDIs for the same transaction.

If you cancel with reason 01 first, the SAT rejects the request because you have no replacement UUID to give. And if you cancel with reason 02 "to save yourself a step" and then issue the new invoice with no relationship, you break the paper trail: in an audit, that new invoice looks like a different transaction.

Here's the whole flow, end to end:

Deadlines and the cases where a cancellation needs the recipient's acceptance have their own fine print. The CFDI cancellation guide covers them.

Relationship type 04: what the SAT checks and what it doesn't

When you stamp the replacement CFDI, the PAC checks that the related UUID has a valid format. But at that point the SAT doesn't check whether the original CFDI really has errors, or whether you'll cancel it later. That has two practical consequences.

The first: you can issue the replacement calmly, review it, and only then fire off the cancellation. Nothing forces you to finish the second step within minutes of the first.

The second is less friendly. Since the SAT doesn't force you to complete the cycle, I've seen production systems with dozens of "replaced" invoices whose original was never canceled. Each of those pairs counts the income twice for the SAT, and the error doesn't surface until accounting reconciles against the SAT's records, such as the pre-filled annual tax return. If you automate the replacement, automate the check of both UUIDs' final status too.

Common mistakes when replacing a CFDI

Replacing a PUE (paid in full when the CFDI is issued, Pago en una sola exhibición) invoice that was paid with a different form of payment (how the customer paid: cash, bank transfer, card; the FormaPago key). If the original invoice went out as PUE with form of payment 01 (Efectivo, cash) but the customer ended up paying by bank transfer, the right fix is to replace the CFDI with the real form of payment. The common mistake is trying to "fix" it with a payment complement (the complement that records each payment received against a PPD invoice; the type P CFDI that carries it is also called REP), which only applies to PPD (paid in installments or later, Pago en parcialidades o diferido) invoices. The Spanish-language PUE vs PPD guide explains the difference between the two.

Replacement chains. You replaced an invoice and the replacement also came out wrong. You can replace the replacement (the new one relates the second CFDI's UUID with 04, not the first one's), but each link in the chain has to close its own cancellation cycle. A chain of three invoices where only the last one is active and the two earlier ones are canceled is valid. Three active invoices for the same transaction is an audit problem.

Relating the wrong UUID. The CfdiRelacionados node accepts whatever UUID you put in it, as long as the format is valid. If you relate another invoice's UUID by mistake, stamping goes through and the disaster turns up weeks later. Validate against your database before you stamp, not after.

Replacing in a later fiscal year than the deduction. If your customer already deducted the original invoice in 2025 and you replace it in 2026, the active CFDI is dated in a different fiscal year from the deduction. The tax effects of this scenario depend on the case. What matters operationally is avoiding it: replace within the same fiscal year whenever you can.

How to automate CFDI replacement

Doing this flow by hand on the SAT portal is workable for two invoices a month. For a system that invoices at volume, the replacement has to be an operation in your backend: issue the replacement with its relationship type 04, cancel the original with reason 01, and check both statuses, all in a controlled sequence with retries.

Fiscalapi's API exposes issuance with related CFDIs, and cancellation with a reason and a replacement UUID, as REST calls in JSON, so you don't build the relationship XML by hand. The full flow is in the Fiscalapi documentation, and the official SDKs include integration examples.

Frequently asked questions about CFDI replacement