When KSeF treats an invoice as a duplicate
KSeF looks for duplicates across every invoice stored in the system. Three fields decide:
- the seller's NIP,
Podmiot1:NIP; - the invoice type,
RodzajFaktury; - the invoice number,
P_2, which the FA(3) schema says must identify the invoice unambiguously.
Uniqueness lasts 10 full years, counted from the end of the year in which the invoice was issued. The seller's NIP always counts: when several branches or units issue invoices on behalf of one company, they have to agree on their numbering.

What the answer carries, and what Odoo keeps
In the KSeF answer, status 440 has the description “Duplikat faktury” (duplicate invoice) and two fields in extensions: originalKsefNumber, the KSeF number of the invoice already in the system, and originalSessionReferenceNumber, the session it came in. The API documentation's example puts a message like “Duplikat faktury. Faktura o numerze KSeF: … została już prawidłowo przesłana do systemu w sesji: …” in details.
In Odoo 18, 19 and 20 the l10n_pl_edi module sets “KSeF Status” to Rejected and adds “KSeF Status: Rejected (Code: 440). Duplicate invoice.” to the history (in Polish on 18 and 19: “Status KSeF: Odrzucono (Kod: 440). Powielona faktura.”). Odoo does not store extensions, so the KSeF number of the original is not on the invoice. As P_2, Odoo writes the invoice number from Odoo.
Where a duplicate comes from with Odoo invoices
| Situation | What happens |
|---|---|
| The invoice already reached KSeF through another channel and was then sent from Odoo | The original is in KSeF; the new sending gets 440. |
| The same NIP issues from two Odoo databases or companies with identical sequences | Two different invoices share type and number. |
| Branches of one company keep separate numbering that overlaps | KSeF counts the seller's NIP, not the branch. |
Odoo only sends invoices without a KSeF status. An invoice in Sent or Accepted cannot be sent a second time by accident from the same Odoo.
How to solve it
- Find where the original is: the KSeF number in
originalKsefNumber, or the invoice with that number in KSeF. - If it is the same invoice, sent earlier through another channel, do not send it again. Every new sending under that number gets 440.
- If it is a different invoice with the same number, the problem is the numbering: agree with your accountants on separate sequences for each database, company or branch with the same NIP.
Is the invoice in KSeF after a 440?
Yes. KSeF holds the original invoice, the one in originalKsefNumber. Only the new sending was rejected.
How long does KSeF remember an invoice number?
For 10 full years from the end of the year of issue. Until then, the same NIP, type and number give 440.

With our module
Poland KSeF 2.0 Validator does not send invoices, but it has a “Mark accepted by KSeF” button for an invoice uploaded to KSeF outside Odoo, with the KSeF number the system gave. If l10n_pl_edi later sends that invoice as well and KSeF rejects it, the module keeps it Accepted and adds: “KSeF rejected the new sending of this invoice by l10n_pl_edi, already accepted by KSeF with KSeF number …: it stays Accepted.”. In every other case it takes the Rejected status from l10n_pl_edi, without the 440 code.
Keep reading
Checked in the module's source code (version 20.0) and the linked sources
Sources
- Module source code: flexigo_poland_ksef_2_0_e_invoice_connector_and_migrati 20.0 (ba7c60f1): i18n/pl.po
- github.com/CIRFMF/ksef-api/blob/ce3670ea042de380039de4c5849fd6455811b292/open-api.json
- github.com/CIRFMF/ksef-api/blob/ce3670ea042de380039de4c5849fd6455811b292/faktury/weryfikac
- github.com/CIRFMF/ksef-client-csharp/blob/a66cbc669814e6c2a615748a13a0a04a650ba04f/KSeF.Cl
- github.com/CIRFMF/ksef-api/blob/ce3670ea042de380039de4c5849fd6455811b292/faktury/schemy/FA
- github.com/odoo/odoo/blob/2982b5f44af03fae6a9888f20632c1cc19f623ba/addons/l10n_pl_edi/mode
- github.com/odoo/odoo/blob/4d2d4b5895db70596863df941d9a1f0beeb117f8/addons/l10n_pl_edi/mode
- github.com/odoo/odoo/blob/2fec20391a8a61ea3a3bf15e9f24d59dba910a8d/addons/l10n_pl_edi/mode
- github.com/odoo/odoo/blob/2982b5f44af03fae6a9888f20632c1cc19f623ba/addons/l10n_pl_edi/i18n
- github.com/odoo/odoo/blob/2fec20391a8a61ea3a3bf15e9f24d59dba910a8d/addons/l10n_pl_edi/i18n
- github.com/odoo/odoo/blob/2fec20391a8a61ea3a3bf15e9f24d59dba910a8d/addons/l10n_pl_edi/data
- github.com/odoo/odoo/blob/2fec20391a8a61ea3a3bf15e9f24d59dba910a8d/addons/l10n_pl_edi/mode
- github.com/odoo/odoo/blob/2fec20391a8a61ea3a3bf15e9f24d59dba910a8d/addons/l10n_pl_edi/mode
- github.com/odoo/odoo/blob/2fec20391a8a61ea3a3bf15e9f24d59dba910a8d/addons/l10n_pl_edi/mode
- Module source code: flexigo_poland_ksef_2_0_e_invoice_connector_and_migrati 20.0 (ba7c60f1): models/account_move.py
- Module source code: flexigo_poland_ksef_2_0_e_invoice_connector_and_migrati 20.0 (ba7c60f1): views/account_move_views.xml
