One-minute summary
Four years into mandatory nómina electrónica, Colombian SMBs are still losing up to 15 % of their annual payroll cost as an income-tax deduction — not because they failed to pay salaries, but because their XML reaches the DIAN broken. Here are the seven mistakes we find in roughly one out of every two DSNE audits.
The Documento Soporte de Nómina Electrónica (DSNE) is not just another piece of paper
. It is the main bridge between PILA, withholding (form 350) and the income-tax return. If the DSNE is wrong, DIAN audits can disallow the cost under article 771-2 of the Tax Code. As of 2026, the DSNE / PILA / worker-RUT cross-check runs automatically: what used to be a manual sample is now an algorithm that flags discrepancies in seconds.
- The DSNE must reach the DIAN within the first 10 calendar days of the month following the payroll period.
- Late filing puts the deductibility of payroll costs at risk (Art. 771-2 of the Tax Code).
- In April 2026 the DIAN clarified: late transmission is technically allowed, but it does not guarantee the deduction on audit.
- The seven mistakes: 10-day window, fixes through duplicates, misclassified concepts, missing special-regime workers, invalid CUNE, stale NIT or cédula, and PDFs that look like compliance but never transmit.
- The fix: cron alerts, a closed concept table, native integration between Odoo HR and
l10n_co_nomina_electronica, and a monthly mini-audit.
What the DSNE is — and what changed in 2026
DIAN Resolution 013 of 2021 made nómina electrónica mandatory for every employer in Colombia. The rollout came in waves by company size: it started with employers of more than 250 workers in September 2021 and finished by reaching one-worker companies at the end of 2023. In 2026 the DSNE is mandatory for every formal employer, regardless of size.
The idea is simple: DIAN wants the same numbers in three places — the DSNE (what you declared as a payroll cost), PILA (what you paid into ARL, EPS, AFP and parafiscales), and the income-tax return (what you deducted as an expense). Any gap between the three sources lights up an automatic flag in audit triage.
Technically, the flow is this: the ERP generates the XML following the Anexo Técnico Nómina Electrónica v 1.0 (DIAN's UBL extension), signs it with a qualified digital certificate, and transmits it to the DIAN Electronic Service. If the XML validates, DIAN returns a CUNE (Código Único de Nómina Electrónica), a SHA-384 hash over the key fields. The CUNE is the only real proof of transmission — without it, the document does not exist for the DIAN.
The seven mistakes we see in every DSNE audit
Each one comes with the real leakage number and the concrete fix in Odoo. They are not ordered by severity but by frequency: #7 is the most dangerous, which is why we save it for the end.
#1. Transmitting outside the 10-day window
Payroll period closes on November 30 → the DSNE must reach the DIAN by December 10. Many accountants close the month on the 18th or 20th because that's how PILA always worked
, and end up a week or two past the DSNE deadline.
SMB with 50 workers, average wage of 2.5 M COP/month → annual payroll cost ≈ 1.8 B COP. At an effective income-tax rate of 35 %, the potential deductibility loss is around 630 M COP/year (≈ USD 148 k).
In April 2026 INCP published a DIAN clarification: late transmission is technically allowed, but the audit still has the right to disallow the deduction. The 10-day window is not a soft guideline; it is a direct cash-flow risk.
How to close it in Odoo: an ir.cron with an alert five days before the cutoff. If the DSNE has not transmitted by day −3, fire a Slack or WhatsApp message to the CFO and create a CRM task. Our Odoo audit framework ships this check by default.
#2. Fixing through a duplicate instead of a Documento de Ajuste
The accountant spots an error in an already-transmitted DSNE — for example, a recurring bonus miscalculated. Instead of generating the Documento Soporte de Ajuste de Nómina Electrónica (a separate document type that references the original CUNE with a cause code), they issue a fresh DSNE for the same amount.
Result: DIAN ends up with two conflicting documents for the same worker and same period. PILA shows a third number. The cross-check flags the case for audit and the company has to explain a discrepancy it cannot defend.
How to close it: an Odoo payroll workflow with an explicit Correction button that generates the Documento de Ajuste with an explicit reference to the original CUNE and the cause code (cod. 1 = correction, cod. 2 = annulment). Block duplication at the ORM model level — that catches most mistakes before transmission.
#3. Earnings and deduction concepts misclassified
DIAN keeps a closed concept table in the Anexo Técnico (table 5.1.1 for earnings, 5.1.2 for deductions). The recurring misses we see:
- Auxilio de transporte (code 102, exempt) is logged as
other allowance
(code 156, taxable). - Statutory prima de servicios (code 201) is confused with extra-legal prima (code 202, contractual).
- Recurring bonus vs. one-off — flips the withholding from 35 % to 0 %.
- Vacation taken vs. cashed out — different codes, different bases.
Misclassification → inconsistent form 350 → audit risk and delayed VAT refund. The damage is not immediate: it shows up two or three months later, after DIAN cross-checks the numbers and the cash is already spent.
How to close it: a concept_id → dian_code mapping table covered by a unit test on every deploy of the l10n_co module. The auditor pulls a 10-worker sample each quarter and matches it against the Anexo Técnico.
#4. Special regimes left uncovered
Many accountants assume nómina electrónica only applies to normal
workers under an indefinite-term contract. In practice, the DSNE covers:
- SENA apprentices during the classroom phase (they contribute to ARL and receive a maintenance allowance below the legal minimum wage).
- Contractors with side benefits paid through payroll (meals, transport, insurance).
- Company pensioners when they receive payments directly from the company.
- Foreign workers with a cédula de extranjería (CE), PEP or salvoconducto.
How to close it: audit the HR base — every person who receives a recurring payment needs an explicit employee_category mapped to DSNE obligation. Any category without justification gets flagged for review.
#5. Invalid CUNE after a manual XML edit
The CUNE is generated as a SHA-384 hash over: NumNE + FecNE + HorNE + NitOFE + DocEmp + ValDev + ValDed + ValTotPago + ClaveTecnicaNomina. If any of those fields changes after the hash is built, the CUNE fails to validate and DIAN rejects the document.
Common scenario: the company issues the DSNE, spots a typo in the worker's cédula, and the accountant fixes it by hand
in the XML before sending. After transmission, DIAN returns a rejection with code ZR01 (CUNE no concuerda) and the document has to be rebuilt from scratch.
How to close it: make the XML read-only after the CUNE is generated. Any change triggers: regenerate the CUNE → re-sign with the digital certificate → new transmission. In Odoo, the nomina.electronica model gets locked fields plus a mandatory _check_company_auto. No more fixing the XML by hand
.
#6. Employer NIT or worker cédula out of date
The company changes its legal name → updates the RUT at the DIAN → but the HR module keeps emitting the DSNE with the old employer data. Or a new worker has a typo in their cédula (eight digits instead of ten), captured in Odoo as passport
by default, and DIAN rejects it when cross-checking against the Registraduría Nacional.
How to close it:
- Regex validation on cédula by document type (CC: 8-10 digits, CE: 6-10, passport: alphanumeric).
- Monthly cron: pull the employer's RUT from the DIAN web service, compare against the Odoo master record, and alert on any drift.
- For foreign workers, an explicit
tipo_documentofield with a required selection (CE, passport, PEP, salvoconducto).
#7. The system prints the PDF payslip but never transmits the XML
The most dangerous and the most common. The ERP generates the PDF for the worker, emails it, and archives a copy at the company. Everyone assumes the DSNE went to DIAN. A quick check shows: no transmission ever happened.
Anonymous case: SMB in professional services, 75 workers. Our audit found that for 14 consecutive months they emitted payslip PDFs to employees, but DIAN never received a single XML. The cause: the l10n_co_nomina_electronica module was installed but not activated in HR settings, and nobody noticed because payments went through the bank, PDFs reached workers, and no formal complaint surfaced. The potential deductibility loss across 14 months of payroll cost was roughly 2.1 B COP (≈ USD 493 k).
How to detect it: log into the DIAN portal → Consulta de DSNE
section → pull the list of transmitted documents per period. Reconcile against HR payroll totals. Any non-zero gap is a fire to put out today.
When this angle applies — and when it doesn't
Not everyone needs a DSNE audit tomorrow. The short checklist:
Review urgently if:
- You have Odoo HR installed but are not sure whether
l10n_co_nomina_electronicais actually active. - The accountant uses external payroll software (Defontana, Siigo, World Office) with no ERP integration.
- You have more than 10 workers and a potential deductibility risk above 50 M COP/year.
- You haven't run an external DSNE compliance audit in the last three years.
Not your case if:
- You are an individual with no employees (no obligation under Resolution 013/2021).
- You work with a certified PSE (Electronic Service Provider) that ships a monthly SLA on CUNE acceptance rate and transmission time.
- You already have a BI dashboard with monthly metrics: transmission time per period, CUNE acceptance rate, rejected concepts, and PILA-vs-DSNE matching percentage.
Actionable checklist: do this week
- Log into the DIAN micrositio →
Consulta DSNE
section → check the date of the last transmitted document. - Download last month's XML and validate the CUNE manually with a SHA-384 calculator.
- Reconcile five workers: DSNE total = payroll total for the period.
- Set up a recurring calendar block: payroll close + five-day buffer before the DIAN cutoff, with a CFO alert.
- Audit concepts against Anexo Técnico v 1.0 — a 10-worker sample across different categories.
What's next
If you recognized at least two of the seven mistakes in your own process, you already have an annual leak of at least 3 M to 15 M COP. A DSNE audit takes five business days, covers the last 12 transmitted months, and ends with a concrete action plan per finding.
Related reading: Odoo in Colombia: full l10n_co localization · DIAN 2026: full timeline of changes · Odoo Colombia rescue projects · Odoo audit: our framework · Odoo Colombia implementation from scratch.
Frequently asked questions
What do we do with DSNE duplicates already sitting at the DIAN?
Generate a Documento Soporte de Ajuste with cause code 2 (annulment) for each duplicate. The original DSNE stays; the duplicates are cancelled.
Do it within 10 days of detection. Otherwise the audit trail keeps the discrepancy, and the case is automatically flagged for fiscal review.
I missed the 10-day window — did I lose the deduction for good?
Not automatically. The INCP-DIAN clarification from April 2026 confirms that late transmission is technically allowed, but the DIAN keeps the right to disallow the deduction on audit under Art. 771-2 of the Tax Code.
In practice: every late case lands in a review pool with full auditor discretion. There are no guarantees. Always transmit on time.
Do SENA apprentices with a maintenance allowance need a DSNE?
Yes. Any payment to an individual in a labor or related relationship requires a DSNE. The classroom and productive phases are both covered.
How much does it cost to bring the Odoo process into compliance?
Audit (five business days): 5 M-15 M COP. Activating and configuring l10n_co_nomina_electronica, training the HR team, and integrating with a PSE: 20 M-60 M COP.
Avoidable penalties reach 33-35 % of annual payroll cost. Payback is usually under two months.
Do PILA and DSNE have to match 100 %?
Ideally, yes. Gaps above 5 % land automatically in the DIAN red-flag pool and get pushed to priority audit.
Monthly reconciliation is mandatory for any SMB with more than 10 workers. Don't leave it for year-end.
Which software complies without patches and workarounds?
Native integrated stacks work: Odoo + l10n_co_nomina_electronica + a certified PSE. Local certified packages also work (World Office, Siigo, Alegra with the payroll module).
Excel plus manual upload to the DIAN portal, above 20 workers, is a risk that no longer makes sense.
How do I confirm my l10n_co_nomina_electronica module is really active?
In Odoo go to Apps → search for l10n_co_nomina_electronica. If the button says Install
, it isn't active. If it says Upgrade
, it's active but may need a migration.
Then go to Settings → Human Resources → Nómina Electrónica. If the menu does not appear, the module is installed but the DIAN credentials were never loaded — and nothing will transmit.
