🇨🇴ColombiaAnálisis

Errores de Retenciones en DIAN: Códigos, Causas y Solución para Equipos de Desarrollo

Los 9 errores más frecuentes al declarar retenciones (reteRenta, reteIVA, reteICA) en factura electrónica DIAN: códigos de rechazo, causa raíz y acción correctiva.

Ing. Carlos Méndez
Arquitecto de Software · Integraciones Fiscales LATAM
10 min lectura11 de septiembre de 2026
Errores de Retenciones en DIAN: Códigos, Causas y Solución para Equipos de Desarrollo

Ing. Carlos Méndez | Septiembre 2026

Ing. Carlos Méndez es arquitecto de software con más de 10 años integrando sistemas fiscales en América Latina. Ha liderado implementaciones de facturación electrónica en Colombia, México y Centroamérica para ISVs de mediana y gran escala.

Los errores de retenciones en la factura electrónica colombiana rara vez son errores de transmisión o de firma. Son errores de lógica de negocio: bases mal calculadas, TaxScheme IDs intercambiados, PayableAmount sin descontar las retenciones, o campos obligatorios omitidos porque la documentación oficial los marca como condicionales. La DIAN los rechaza en tiempo real con códigos específicos que, si se leen correctamente, apuntan exactamente al campo que falló.

Este artículo documenta los 9 errores más frecuentes relacionados con retenciones en la factura electrónica colombiana, organizados por tipo: errores de estructura XML, errores de cálculo matemático y errores de lógica de activación. Para cada uno se indica la causa raíz más probable y la acción correctiva concreta.

Errores de estructura XML en WithholdingTaxTotal

Error 1: TaxScheme/ID incorrecto o no válido

Código DIAN: FAD09 o variante de error de esquema tributario. Causa raíz: el campo cac:TaxScheme/cbc:ID dentro de WithholdingTaxTotal contiene un valor no permitido. Los únicos valores válidos para retenciones son '04' (reteIVA), '06' (reteRenta) y '07' (reteICA). Errores frecuentes: usar '1' en vez de '01' para IVA (pero ese va en TaxTotal, no en WithholdingTaxTotal), usar '6' en vez de '06' para reteRenta, o usar nombres de texto como 'RETEFUENTE' en el campo ID en lugar del número. Acción correctiva: verificar que el ID sea siempre una cadena de dos dígitos con cero a la izquierda. El campo Name sí acepta el nombre textual ('RETEFUENTE', 'RETEIVA', 'RETEICA'), pero el campo ID debe ser numérico.

Error 2: WithholdingTaxTotal ubicado dentro de TaxTotal

Código DIAN: error de validación de esquema XML. Causa raíz: el bloque WithholdingTaxTotal se ubicó como hijo de TaxTotal en lugar de como elemento hermano al mismo nivel. Son elementos XML distintos: TaxTotal (impuestos que cobra el emisor) y WithholdingTaxTotal (retenciones del receptor) deben ser hijos directos de Invoice, al mismo nivel jerárquico, no anidados uno dentro del otro. Acción correctiva: revisar el generador de XML para asegurar que la jerarquía del documento place ambos elementos como hijos directos de Invoice, sin anidamiento entre ellos.

Error 3: TaxAmount en nivel raíz diferente al TaxAmount del TaxSubtotal

Código DIAN: FAD10 o equivalente de inconsistencia de montos. Causa raíz: el cbc:TaxAmount que va directamente dentro de WithholdingTaxTotal y el cbc:TaxAmount dentro de cac:TaxSubtotal deben ser iguales cuando hay un solo TaxSubtotal. Si el generador calcula uno y copia el otro con un redondeo diferente, la diferencia de 1 peso produce rechazo. Acción correctiva: calcular el TaxAmount una sola vez y reutilizar el mismo valor en ambos campos. No calcular dos veces independientemente.

Errores de cálculo matemático

Error 4: Base de reteIVA calculada sobre el valor neto en lugar del IVA

Causa raíz: el cádigo usa el mismo LineExtensionAmount como TaxableAmount para reteIVA y para reteRenta. Para reteIVA, el TaxableAmount debe ser el monto del IVA (lo que está en TaxTotal con ID 01), no el valor del bien. El valor de reteIVA resulta entonces incorrecto (15% de $1.000.000 = $150.000 en lugar de 15% de $190.000 = $28.500), y la DIAN detecta que el porcentaje Percent * TaxableAmount no da TaxAmount. Acción correctiva: en el motor de cálculo, separar explícitamente la función calcularBaseReteRenta (devuelve valor neto) de calcularBaseReteIVA (devuelve valor del IVA ya calculado).

Error 5: Tarifa de reteICA expresada en por mil en vez de porcentaje

Causa raíz: el campo cbc:Percent en el bloque de reteICA contiene el valor '6.9' (expresado como por mil) en lugar de '0.69' (expresado como porcentaje). La DIAN valida que TaxableAmount * (Percent/100) = TaxAmount. Con Percent = 6.9, el sistema espera que TaxAmount sea 10 veces mayor al real, produciendo rechazo por inconsistencia matemática. Acción correctiva: al configurar la tarifa de ICA municipal en el catálogo, almacenarla en la unidad 'por mil' para legibilidad humana, pero convertirla a porcentaje (dividir por 10) antes de escribirla en el campo Percent del XML.

Error 6: PayableAmount no descuenta la suma de retenciones

Causa raíz: el cálculo del PayableAmount en LegalMonetaryTotal no resta el total de WithholdingTaxTotal/TaxAmount. El PayableAmount correcto es TaxInclusiveAmount menos la suma de todas las retenciones. Si solo se agrega el bloque WithholdingTaxTotal al XML pero no se actualiza el PayableAmount, la DIAN detecta inconsistencia entre los totales declarados y los bloques de retención presentes. Acción correctiva: implementar el cálculo de PayableAmount como la última operación del generador de XML, después de que todos los bloques de retención hayan sido calculados y agregados.

Error 7: Redondeo inconsistente entre base, porcentaje y monto

Causa raíz: la multiplicación TaxableAmount * (Percent/100) produce un valor con decimales, y el sistema redondea de forma diferente al calcular el TaxAmount. La DIAN tiene una tolerancia de 1 peso (no de 1 centavo). Errores superiores a 1 peso producen rechazo. Acción correctiva: usar aritmética de punto fijo (BigDecimal o equivalente) para todos los cálculos de retención. Nunca usar float o double para montos fiscales. Definir una sola función de redondeo (HALF_UP a 2 decimales) y usarla consistentemente en toda la cadena de cálculo.

Errores de lógica de activación

Error 8: Incluir retenciones para un emisor en régimen SIMPLE

Código DIAN: error de régimen tributario incompatible. Causa raíz: el motor incluye bloques WithholdingTaxTotal para reteRenta o reteIVA aunque el emisor está en el régimen SIMPLE, que está exento de estas retenciones. La DIAN identifica el régimen del emisor por el NIT y rechaza el documento si detecta retenciones que no corresponden al régimen. Acción correctiva: agregar una verificación del régimen tributario del emisor como primer paso del flujo de activación de retenciones. Si el emisor está en SIMPLE, omitir los bloques de reteRenta y reteIVA completamente.

Error 9: Retenciones de un tipo incluidas múltiples veces en lugar de consolidadas

Causa raíz: el generador de XML crea un bloque WithholdingTaxTotal ID 06 por cada línea de la factura en lugar de uno consolidado para todo el documento. La DIAN acepta múltiples bloques del mismo ID cuando tienen justificación (por ejemplo, dos municipios con reteICA diferente), pero no cuando son duplicados del mismo concepto. El rechazo se produce porque la suma de los TaxAmount de los bloques duplicados no coincide con el descuento del PayableAmount. Acción correctiva: el generador debe agregar retenciones del mismo TaxScheme ID en un solo bloque a nivel de documento, con la base total y el monto total calculados sobre el conjunto de líneas.

Tabla resumen: errores, causa y acción correctiva

Error 1 — TaxScheme ID inválido. Causa: valor no numérico o sin cero inicial. Fix: siempre '04', '06' o '07'. Error 2 — WithholdingTaxTotal anidado en TaxTotal. Causa: error de jerarquía XML. Fix: ambos elementos al mismo nivel como hijos de Invoice. Error 3 — TaxAmount raíz distinto al de TaxSubtotal. Causa: doble cálculo con redondeo diferente. Fix: calcular una vez y reusar. Error 4 — Base reteIVA calculada sobre valor neto. Causa: misma función para todas las bases. Fix: función separada que usa el valor del IVA. Error 5 — Tarifa reteICA en por mil en Percent. Causa: confusión de unidad. Fix: convertir a porcentaje (dividir por 10). Error 6 — PayableAmount sin descontar retenciones. Causa: cálculo anterior a agregar retenciones. Fix: calcular PayableAmount al final. Error 7 — Redondeo inconsistente. Causa: uso de float. Fix: usar BigDecimal con HALF_UP. Error 8 — Retenciones en emisor SIMPLE. Causa: verificación de régimen omitida. Fix: verificar SIMPLE antes de activar retenciones. Error 9 — Mismo TaxScheme ID duplicado. Causa: retenciones generadas por línea. Fix: consolidar por documento.

Cómo prevenir estos errores desde el diseño del motor de facturación

Los nueve errores descritos tienen un denominador común: se producen cuando la lógica de retenciones se implementa como un bloque único que genera XML sin una capa intermedia de validación. La mejor arquitectura para evitarlos es una cadena de tres pasos: primero, un módulo de determinación de retenciones (qué tipos aplican y con qué bases, según el emisor, el comprador y el tipo de bien o servicio); segundo, un módulo de cálculo (que produce los montos usando aritmética de punto fijo y un único método de redondeo); tercero, un módulo de generación XML (que solo convierte los objetos calculados en bloques UBL 2.1, sin cálculos adicionales). Esta separación hace que cada tipo de error sea trazable a un solo módulo y eliminable sin afectar los demás.

La DIAN publica los códigos de error de validación en los Anexos Técnicos de factura electrónica disponibles en el portal de la DIAN. La versión vigente del Anexo Técnico es la 1.8. Los códigos de error de retenciones se agrupan en las secciones de validación de totales (FAD09-FAD15) y de validación de esquema tributario (FAX-series). Tener el Anexo Técnico disponible en el entorno de desarrollo del equipo es la forma más eficiente de diagnosticar rechazos sin depender de soporte de terceros.

Preguntas frecuentes sobre errores de retención en DIAN

¿Cuál es el código de error DIAN más frecuente en errores de retenciones?

El más frecuente es el grupo de errores FAD (Falla en Arithmética del Documento) relacionados con inconsistencias entre totales. Específicamente, FAD09 (error en WithholdingTaxTotal) y FAD10 (error en PayableAmount que no refleja las retenciones) aparecen en la mayoría de los rechazos relacionados con retenciones en integraciones nuevas. La segunda categoría más frecuente es la de errores de esquema XML cuando el TaxScheme ID no es válido.

¿Cómo puedo probar el cálculo de retenciones antes de transmitir a producción?

El ambiente de pruebas de la DIAN (habilitación y sandbox) ejecuta las mismas validaciones matemáticas y de estructura que producción. Transmitir documentos con todos los tipos de retención en el sandbox antes de go-live es la práctica más efectiva. Adicionalmente, implementar unit tests que validen cada caso de cálculo (retención simple, retención múltiple, emisor SIMPLE, autorretenedor) ahorra ciclos de depuración en producción.

¿Qué diferencia hay entre un error de estructura y un error matemático en la respuesta de la DIAN?

Los errores de estructura XML se producen antes de que la DIAN ejecute las validaciones de negocio: el documento no pasa ni siquiera el parseo del schema. El mensaje de respuesta incluye la ruta XPath del elemento inválido. Los errores matemáticos ocurren después del parseo exitoso, cuando el motor de validación de la DIAN cruza los valores declarados. El mensaje incluye los valores esperados y recibidos para los campos en conflicto. Distinguir entre ambos tipos permite diagnosticar rápidamente si el problema está en el generador de XML o en el cálculo de montos.

¿Es posible reenviar una factura con error de retenciones sin emitir una nota crédito?

Solo si el documento fue rechazado (no aceptado) por la DIAN. Un documento rechazado no tiene CUFE válido y puede retransmitirse corregido con el mismo número de factura. Si el documento fue aceptado por la DIAN (CUFE generado) con retenciones incorrectas, no es posible modificarlo: la corrección requiere una nota crédito que anule la factura original, seguida de una nueva factura con las retenciones correctas. Por eso la validación previa a la transmisión es más valiosa en el caso de retenciones que en cualquier otro campo del documento.

Sobre el autor

Ing. Carlos Méndez es arquitecto de software con más de 10 años integrando sistemas fiscales en América Latina. Ha liderado implementaciones de facturación electrónica en Colombia, México y Centroamérica para ISVs de mediana y gran escala.