DAT
Documentación

Códigos de error

Estos son los códigos de error comunes a las bibliotecas de servicio con soporte oficial de DAT.

Cada código lleva dos valores — impacto y reintento — y algunos reciben además la etiqueta sospecha.

Impacto — el golpe que recibe el servicio

Es el criterio para lanzar una alerta. Solo se mira una cosa: "¿está el servicio detenido ahora mismo?".

ImpactoSignificadoEjemplo
CríticoEl servicio o una función concreta se detiene. Emisión imposible, sincronización con fallo permanente, fallo de inicializaciónEl servidor emisor no tiene ni un solo certificado utilizable
ParcialAlgunas peticiones o ciclos fallan, pero el servicio sigue funcionando. Por lo general se recupera soloFalla un ciclo del CMS. Todo continúa con los certificados ya existentes
Sin impactoSe rechaza una petición y ya estáLlega un token manipulado. Basta con filtrarlo

Sin impacto no es un caso de alerta. Si todo el equipo de guardia tuviera que revisar porque llegó una entrada errónea una sola vez, la alerta perdería todo su sentido.

Sospecha — investigar si persiste

Los códigos con la etiqueta Sospecha forman parte de la operación normal cuando aparecen de forma aislada. Un cliente puede enviar valores erróneos en cualquier momento, y el papel de la biblioteca es precisamente filtrarlos.

Ahora bien, si estos errores se producen de forma persistente o concentrados desde un origen concreto, se trata de uno de estos dos casos.

  • Anomalía de configuración — un despliegue incorrecto, clientes de una versión antigua que siguen activos, o certificados desalineados.
  • Intento de intrusión — un intento de superar la verificación con tokens o claves manipulados, o un sondeo en busca de valores válidos.

Por eso, para estos códigos lo correcto es registrar el número de ocurrencias como métrica. Basta con avisar cuando se supere un umbral.

Reintento

ReintentoSignificado
TransitorioSe resuelve reintentando tras un backoff
PermanenteNo reintentar. Hay que corregir la configuración o la entrada
EstadoNo es un error, sino una señal

Token

Problemas con la propia cadena del token recibido.

DAT_TOKEN_MALFORMEDSin impactoPermanenteshieldSospecha

Las partes separadas por puntos no son exactamente cinco, expire no es decimal puro, cid no es hexadecimal puro, plain o secure no están en base64url, o un campo numérico supera el rango entero representable.

arrow_forwardRechazar la petición

DAT_TOKEN_EXPIREDSin impactoPermanente

expire <= now. El instante exacto también cuenta como expirado — si expire == now, el token ya está expirado.

arrow_forwardInducir la reemisión del token

DAT_TOKEN_UNKNOWNParcialPermanente

Un error de token que no encaja en ninguna de las categorías anteriores.

arrow_forwardRevisar los registros

Nunca confundas expiración con error de formato

Las reacciones son opuestas: la expiración es un fin de vida normal y basta con hacer renovar el token; un error de formato significa que el token nunca fue emitido por nosotros y debe rechazarse.

El análisis determina primero la estructura y solo después examina los valores. Una cadena como "1.2.3", a la que le faltan partes, no es un token expirado sino que no es un token en absoluto: por eso es DAT_TOKEN_MALFORMED.

Un signo en el campo expire, como +100, tampoco es una expiración sino un error de formato. Solo se admiten dígitos ASCII puros.


Certificado

El formato de la cadena del certificado y la cuestión de si ese certificado puede usarse ahora.

DAT_CERT_MALFORMEDCríticoPermanente

Las partes separadas por puntos no son exactamente ocho, ha fallado el análisis de cid, start, duration o ttl, un campo de clave no está en base64url, o start + duration + ttl supera u64.

arrow_forwardVolver a desplegar el certificado

DAT_CERT_EXPIREDCríticoPermanente

start + duration + ttl < now. Completamente expirado: no es posible ni emitir ni verificar.

arrow_forwardRenovar el certificado

DAT_CERT_NOT_YET_ISSUABLECríticoTransitorio

now < start. La ventana de emisión todavía no se ha abierto.

arrow_forwardEsperar

DAT_CERT_ISSUANCE_ENDEDCríticoPermanente

now > start + duration, pero aún queda ttl. Ya no se puede emitir, solo verificar.

arrow_forwardDesplegar un certificado nuevo

DAT_CERT_VERIFY_ONLYCríticoPermanente

Un certificado que contiene solo la clave pública, sin la clave privada de firma. Verificar funciona, emitir no.

arrow_forwardRevisar la configuración de despliegue

DAT_CERT_NOT_FOUNDSin impactoPermanenteshieldSospecha

No se dispone de ningún certificado para el cid del token. O bien es un token falsificado, o bien un despliegue erróneo.

arrow_forwardRechazar la petición

DAT_CERT_NOT_SYNCEDParcialTransitorio

Ese cid aún no se ha recibido del CMS. Aparece brevemente justo después de desplegar un certificado nuevo.

arrow_forwardReintentar tras la sincronización

DAT_CERT_DUPLICATE_CIDCríticoPermanente

El mismo cid aparece más de una vez en la lista que se importa.

arrow_forwardRevisar la respuesta del servidor

DAT_CERT_UNKNOWNParcialPermanente

Un error de certificado que no encaja en ninguna de las categorías anteriores.

arrow_forwardRevisar los registros

DAT_CERT_NOT_FOUND y DAT_CERT_NOT_SYNCED presentan los mismos síntomas, pero requieren reacciones distintas. El primero corresponde a un cid que nunca hemos emitido: esperar no cambia nada. El segundo se resuelve en cuanto se produce la sincronización.

Un DAT_CERT_NOT_FOUND aislado basta con filtrarlo; si la cifra crece de golpe, significa que el despliegue se ha desalineado o que circulan tokens falsificados.


Firma

DAT_SIG_MISMATCHSin impactoPermanenteshieldSospecha

La verificación de la firma terminó en discrepancia. El valor HMAC no coincide, o ECDSA verify devuelve false.

arrow_forwardBloquear la sesión, registro de seguridad

DAT_SIG_MALFORMEDSin impactoPermanenteshieldSospecha

La parte de la firma está vacía, no está en base64url, la longitud de r‖s de ECDSA no corresponde a la curva, o falló la conversión a DER.

arrow_forwardRechazar la petición

DAT_SIG_KEY_MISSINGCríticoPermanente

Se intentó firmar con una clave de solo verificación. En tiempo de ejecución no hay clave privada.

arrow_forwardRevisar la configuración del servidor emisor

DAT_SIG_BACKENDParcialPermanente

La operación de firma o verificación no llegó siquiera a ejecutarse. Tipo de clave incorrecto, manejador liberado, o error interno de la biblioteca criptográfica.

arrow_forwardRevisar el tipo de clave y la biblioteca

DAT_SIG_UNKNOWNParcialPermanente

Un error de firma que no encaja en ninguna de las categorías anteriores.

arrow_forwardRevisar los registros

No mezcles la discrepancia con el fallo del backend

Ambos códigos están en ejes opuestos.

  • DAT_SIG_MISMATCH — simplemente una firma entrante que no coincide, por tanto sin impacto en el servicio; en cambio, si persiste, es un caso de sospecha.
  • DAT_SIG_BACKEND — la propia operación de verificación no llegó a ejecutarse: es un problema de nuestro lado y no un caso de sospecha.

Notificar un tipo de clave incorrecto o un fallo de la biblioteca como "discrepancia de firma" mezcla entre los indicadores de ataque una situación en la que en realidad es nuestro código el que está roto. A la inversa, una falsificación real clasificada como error de backend desaparece por completo de las métricas de sospecha.


Cifrado

Problemas de cifrado y descifrado de la carga útil secure.

DAT_CRYPTO_TAG_MISMATCHSin impactoPermanenteshieldSospecha

La etiqueta de autenticación AES-GCM no coincide. O bien secure ha sido manipulado, o bien la clave del certificado es distinta.

arrow_forwardBloquear la sesión, registro de seguridad

DAT_CRYPTO_DATA_INVALIDSin impactoPermanenteshieldSospecha

El texto cifrado no está vacío pero no supera el tamaño del IV (12 bytes), o la entrada excede el límite de la implementación (INT_MAX, etc.).

arrow_forwardRechazar la petición

DAT_CRYPTO_BACKENDParcialPermanente

La operación de cifrado o descifrado no pudo ejecutarse. Plataforma sin soporte de GCM, o fallo al inicializar el contexto.

arrow_forwardComprobar el soporte de la plataforma

DAT_CRYPTO_UNKNOWNParcialPermanente

Un error de cifrado/descifrado que no encaja en ninguna de las categorías anteriores.

arrow_forwardRevisar los registros

Una carga útil secure vacía no es un error. Una entrada vacía produce una salida vacía y no se emite ningún código.

En la ruta que omite la verificación de firma, la etiqueta GCM es la única comprobación de integridad. Por eso DAT_CRYPTO_TAG_MISMATCH no se agrupa con los demás fallos de descifrado bajo un mismo código.


Clave

DAT_KEY_INVALIDSin impactoPermanenteshieldSospecha

La longitud de la clave no coincide con el algoritmo declarado (HMAC 32/48/64, AES 16/32), el punto no está sobre la curva, d ∉ [1,n-1], el formato no es sin comprimir (0x04), o la clave privada y la pública no forman pareja.

arrow_forwardSustituir la clave

DAT_KEY_VERIFY_ONLY_UNSUPPORTEDCríticoPermanente

Se ha solicitado una exportación de solo verificación para un algoritmo de la familia HMAC.

arrow_forwardCambiar de algoritmo

DAT_KEY_UNKNOWNParcialPermanente

Un error de clave que no encaja en ninguna de las categorías anteriores.

arrow_forwardRevisar los registros

Tres casos que se parecen pero son distintos:

CódigoSignificado
DAT_KEY_VERIFY_ONLY_UNSUPPORTEDLímite estructural del algoritmo. HMAC es simétrico y no tiene concepto de clave pública
DAT_SIG_KEY_MISSINGEstado en tiempo de ejecución. Esta clave no contiene ahora mismo una clave privada
DAT_CERT_VERIFY_ONLYForma de despliegue. Este certificado se desplegó como de solo verificación

Gestor

El estado del objeto que guarda los certificados y se usa para emitir y verificar.

DAT_MANAGER_NO_CERTIFICATECríticoTransitorio

No se dispone de ningún certificado. O bien antes de la importación, o bien tras fallar la primera sincronización con el CMS.

arrow_forwardComprobar la conexión con el CMS

DAT_MANAGER_NO_ISSUABLE_CERTIFICATECríticoPermanente

Hay certificados, pero ninguno es utilizable para emitir en este momento. La causa se transmite junto con el error.

arrow_forwardDecidir según la causa — ver la tabla siguiente

DAT_MANAGER_DISPOSEDCríticoPermanente

Se ha usado un gestor o un certificado ya liberado.

arrow_forwardCorregir el código que llama

DAT_MANAGER_UNKNOWNParcialPermanente

Un error de gestor que no encaja en ninguna de las categorías anteriores.

arrow_forwardRevisar los registros

La causa (cause) de DAT_MANAGER_NO_ISSUABLE_CERTIFICATE es una de estas cuatro. Lo que hay que hacer difiere por completo según el origen.

CausaSignificadoReintentoReacción
DAT_CERT_NOT_YET_ISSUABLEAntes del inicio de la ventana de emisiónTransitorioSe resuelve esperando
DAT_CERT_ISSUANCE_ENDEDVentana de emisión cerrada, solo es posible verificarPermanenteHay que desplegar un certificado nuevo
DAT_CERT_EXPIREDTodo el stock está expiradoPermanenteHay que renovar los certificados
DAT_CERT_VERIFY_ONLYTodo el stock es de solo verificaciónPermanenteEs un error de configuración del despliegue

Si el servidor emisor está configurado para recibir únicamente certificados de verificación, aparece DAT_CERT_VERIFY_ONLY. Esperar nunca lo resuelve, así que no es un caso de reintento.


Configuración

Problemas con los valores que pasa quien llama. La familia CONFIG está formada íntegramente por errores que hay que corregir en el código; si aparecen en producción, es que el despliegue es incorrecto.

DAT_CONFIG_ALG_UNSUPPORTEDCríticoPermanente

Nombre de algoritmo desconocido. Debe coincidir exactamente con la notación de transporte (ECDSA-P256, IV-AES256-GCM).

arrow_forwardComprobar el nombre del algoritmo

DAT_CONFIG_ARGUMENT_INVALIDCríticoPermanente

Un argumento obligatorio es null, está fuera del rango permitido (valor de tiempo negativo, interval <= 0), es de un tipo no soportado (un número o un booleano como carga útil en lenguajes de tipado dinámico), o el cuerpo que se va a firmar está vacío.

arrow_forwardCorregir el código que llama

DAT_CONFIG_URI_INVALIDCríticoPermanente

La URI del servidor CMS no se ajusta a la especificación. No se puede analizar, el esquema no es http/https, o lleva una ruta o una cadena de consulta.

arrow_forwardCorregir la URI

DAT_CONFIG_UNKNOWNCríticoPermanente

Un error de configuración que no encaja en ninguna de las categorías anteriores.

arrow_forwardRevisar los registros


Interno

Problemas del entorno de ejecución y del runtime.

DAT_INTERNAL_UNAVAILABLECríticoPermanente

El backend criptográfico o la API del runtime sencillamente no existen. Falta crypto.subtle, la plataforma no soporta AES-GCM, o la versión del runtime es insuficiente.

arrow_forwardComprobar el despliegue y la plataforma

DAT_INTERNAL_UNKNOWNCríticoPermanente

Fallo al reservar memoria, fallo al generar aleatoriedad, fallo al adquirir un bloqueo, o se ha alcanzado una rama diseñada como inalcanzable.

arrow_forwardRevisar los registros

DAT_INTERNAL_UNAVAILABLE se resuelve corrigiendo el entorno de despliegue; DAT_INTERNAL_UNKNOWN suele ser un fallo del runtime o un error de la biblioteca.


Sincronización CMS

Si no se usa la sincronización con el CMS, estos códigos no aparecen.

DAT_CMS_UNREACHABLEParcialTransitorio

Fallo de DNS, conexión rechazada, fallo de TLS, tiempo de espera agotado. El tiempo de espera no tiene código propio y se incluye aquí: la reacción es la misma.

arrow_forwardReintentar tras un backoff

DAT_CMS_UNAUTHORIZEDCríticoPermanente401

El servidor respondió 401. Falta el token o es incorrecto.

arrow_forwardComprobar la configuración del token

DAT_CMS_FORBIDDENCríticoPermanente403

El servidor respondió 403. El token es válido pero no tiene permisos sobre este endpoint.

arrow_forwardComprobar el nivel del token

DAT_CMS_ENDPOINT_NOT_FOUNDCríticoPermanente404

El servidor respondió 404. La URL es incorrecta.

arrow_forwardComprobar la configuración de la URL

DAT_CMS_SERVER_ERRORParcialTransitorio5xx

El servidor respondió 5xx.

arrow_forwardReintentar tras un backoff

DAT_CMS_HTTP_STATUSCríticoPermanente

Una respuesta no-2xx que no corresponde a ninguno de los casos anteriores.

arrow_forwardComprobar el código de estado

DAT_CMS_MALFORMEDCríticoPermanente

La respuesta no tiene línea de versión, la línea de versión no es decimal pura, o supera el rango.

arrow_forwardComprobar la versión del servidor

DAT_CMS_IMPORT_FAILEDCríticoPermanente

La respuesta llegó, pero no se pudieron aplicar los certificados. El origen se transporta en cause.

arrow_forwardRevisar CERT_* / KEY_* en cause

DAT_CMS_VERSION_RESETSin impactoEstado200

El servidor devolvió una versión anterior a la nuestra. Es la instrucción de resincronización completa.

arrow_forwardSe gestiona automáticamente

DAT_CMS_NOT_SYNCEDCríticoTransitorio

Todavía no ha habido ninguna sincronización con éxito.

arrow_forwardEsperar a la primera sincronización

DAT_CMS_SYNC_IN_PROGRESSSin impactoEstado

La sincronización anterior sigue en curso, por lo que se ha saltado este ciclo. No es un error.

DAT_CMS_NOT_SUPPORTEDCríticoPermanente

La funcionalidad CMS no está incluida en la compilación. Feature desactivada o CURL ausente.

arrow_forwardComprobar las opciones de compilación

DAT_CMS_UNKNOWNParcialPermanente

Un error de CMS que no encaja en ninguna de las categorías anteriores.

arrow_forwardRevisar los registros

Los códigos en los que la sincronización se considera fallo permanente (UNAUTHORIZED, FORBIDDEN, ENDPOINT_NOT_FOUND, MALFORMED, IMPORT_FAILED) son todos críticos. Reintentar no resuelve nada mientras los certificados siguen expirando: si se deja sin atender, el servicio acabará necesariamente detenido.

En cambio, UNREACHABLE y SERVER_ERROR son parciales. Todo sigue funcionando con los certificados existentes y la sincronización se recupera sola en el siguiente ciclo — pero si los fallos continúan, al final se pasa a crítico. Coloca la alerta sobre el número de fallos consecutivos.

Los fallos de sincronización no se lanzan como excepción

Aunque falle la primera sincronización, el gestor se devuelve con normalidad: es preferible que la sincronización acabe produciéndose, aunque sea tarde. El fallo, en cambio, queda como estado consultable.

ClienteConsulta
Rustmanager.last_error().await
Gomanager.LastError()
JavaScriptmanager.lastError()
Pythonmanager.last_error()
Rubymanager.last_error
Java/Kotlinmanager.lastError
C#manager.LastError
C/C++dat_cms_manager_last_error(m)

Si nunca ha habido éxito, ahí figura DAT_CMS_NOT_SYNCED; en funcionamiento normal el valor está vacío.


Servidor

Códigos que emite el servidor CMS. Los clientes no los generan, solo los reciben.

DAT_AUTH_UNAUTHORIZEDSin impactoPermanenteshieldSospecha401

Falta la cabecera Authorization, o el token no está registrado en ningún nivel.

DAT_AUTH_FORBIDDENSin impactoPermanenteshieldSospecha403

El token sí está registrado, pero no en el nivel que exige este endpoint.

DAT_AUTH_DISABLEDCríticoEstado

No hay ningún token configurado, por lo que la autenticación está totalmente desactivada. Con ello incluso la API de emisión de certificados queda abierta sin autenticación. No sale en la respuesta, solo se registra en el arranque.

arrow_forwardConfigurar un token de inmediato

DAT_REQ_MALFORMEDSin impactoPermanenteshieldSospecha400

Los parámetros de ruta o de consulta no son interpretables, o un argumento está fuera del rango permitido (delay negativo, más de diez años, etc.).

DAT_REQ_ALG_UNSUPPORTEDSin impactoPermanente400

El nombre de algoritmo de la ruta de la petición es desconocido.

DAT_REQ_NOT_FOUNDSin impactoPermanenteshieldSospecha404·405

Esa ruta no existe o el método es distinto.

DAT_REQ_TOO_LARGESin impactoPermanenteshieldSospecha413

Se ha superado el tamaño del cuerpo de la petición.

DAT_REQ_UNKNOWNSin impactoPermanente400

Un error de petición que no encaja en ninguna de las categorías anteriores.

DAT_STORE_UNAVAILABLEParcialTransitorio503

Conexión con la base de datos perdida, pool de conexiones agotado, contención de bloqueos, tiempo de espera agotado. El único código que usa 503: la señal con la que el cliente sabe que "esto mejora esperando".

arrow_forwardReintentar tras un backoff

DAT_STORE_UNKNOWNCríticoPermanente500

Fallo de lectura o escritura, tabla inexistente, esquema no coincidente, fila de certificado corrupta.

arrow_forwardComprobar el estado de la base de datos

Sobre de respuesta:

json
{
  "code": "DAT_REQ_ALG_UNSUPPORTED",
  "details": { "algorithm": "BOGUS-ALG" }
}

Para los errores que surgen al crear y manipular certificados, el servidor usa tal cual los códigos comunes anteriores (DAT_CERT_*, DAT_KEY_*, DAT_CONFIG_*).

Al recibir un código del servidor

El cliente envuelve el código del servidor en su propio código CMS y conserva el original en cause.

RecibidoHTTPCódigo que emite el cliente
DAT_AUTH_UNAUTHORIZED401DAT_CMS_UNAUTHORIZED
DAT_AUTH_FORBIDDEN403DAT_CMS_FORBIDDEN
DAT_REQ_NOT_FOUND404DAT_CMS_ENDPOINT_NOT_FOUND
DAT_REQ_* (los demás)400·405·413DAT_CMS_HTTP_STATUS
DAT_STORE_UNAVAILABLE503DAT_CMS_SERVER_ERROR
DAT_STORE_UNKNOWN500DAT_CMS_SERVER_ERROR
(retroceso de versión)200DAT_CMS_VERSION_RESET

Buscar por síntoma

SíntomaCódigo
Funciona justo tras iniciar sesión y poco después se rechazaDAT_TOKEN_EXPIRED — Se ha agotado la vida del token. Basta con reemitirlo
La verificación solo falla en un servidor concretoDAT_CERT_NOT_SYNCED — Ese servidor aún no ha recibido el nuevo CID
El mismo token se rechaza en todos los servidoresDAT_CERT_NOT_FOUND — Un CID que nunca hemos emitido
El servidor emisor no consigue crear tokensDAT_MANAGER_NO_ISSUABLE_CERTIFICATE + DAT_CERT_VERIFY_ONLYSe ha desplegado como verify-only
La emisión solo falla justo después del arranqueDAT_MANAGER_NO_CERTIFICATE — Antes de la primera sincronización. Se resuelve en breve
La sincronización con el CMS falla continuamenteDAT_CMS_UNAUTHORIZED — El token es incorrecto. Reintentar no lo resuelve
No llega ni un solo certificadoDAT_CMS_ENDPOINT_NOT_FOUND — Hay una errata en la URL
Solo falla en una plataforma concretaDAT_INTERNAL_UNAVAILABLE — Falta el backend criptográfico
Los fallos de verificación aumentan de golpeDAT_SIG_MISMATCH — Aislado es inofensivo, pero en avalancha es un intento de falsificación
El descifrado de secure falla de golpeDAT_CRYPTO_TAG_MISMATCH — Certificados desalineados o intento de manipulación
Aviso en el registro de arranque del CMSDAT_AUTH_DISABLEDLa autenticación está apagada. La API de emisión está abierta

Apéndice

Sintaxis de los códigos

DAT_<área>_<causa>
  • Cuando la misma causa se produce en áreas distintas, el nombre de la causa es idéntico. DAT_TOKEN_MALFORMED y DAT_CERT_MALFORMED solo se diferencian en el objeto; el significado es el mismo.
  • _UNKNOWN es exclusivamente el repliegue de cada área. No se usa con otro sentido, como "algoritmo desconocido" (para eso está _UNSUPPORTED).
  • La cadena del código es un contrato público. El mensaje puede cambiarse libremente; el código, no.
CategoríaPrefijo de código
TokenDAT_TOKEN_
CertificadoDAT_CERT_
FirmaDAT_SIG_
CifradoDAT_CRYPTO_
ClaveDAT_KEY_
GestorDAT_MANAGER_
ConfiguraciónDAT_CONFIG_
InternoDAT_INTERNAL_
Sincronización CMSDAT_CMS_
ServidorDAT_AUTH_ · DAT_REQ_ · DAT_STORE_

Acceso según el cliente

ClienteTipo de errorCódigoClase de reintentoEvento de seguridad
RustDatError enumerr.code()err.retry()err.security_event()
Go*dat.Errorerr.Codedat.Retry(err)dat.SecurityEvent(err)
JavaScriptDatError extends Errore.codee.retrye.securityEvent
PythonDatError(ValueError, RuntimeError)e.codee.retrye.security_event
RubySaro::Dat::Errore.codee.retrye.security_event?
Java/KotlinDatExceptione.codee.retrye.securityEvent
C#DatExceptione.Codee.Retrye.SecurityEvent
C/C++dat_error_tdat_error_code(e)dat_error_retry(e)dat_error_is_security_event(e)
Servidor CMSSobre JSONcampo code

Evento de seguridad solo devuelve true en los dos casos en los que la falsificación o la manipulación son seguras (DAT_SIG_MISMATCH, DAT_CRYPTO_TAG_MISMATCH). La etiqueta sospecha de este documento abarca más (llega hasta tokens, claves y peticiones manipulados); por ahora es solo una clasificación documental y no se expone en la API del cliente.

El nivel de impacto es igualmente una clasificación documental. Un mismo código puede golpear de forma distinta según dónde surja: DAT_KEY_INVALID, por ejemplo, no tiene impacto cuando sirve para filtrar un token entrante, pero hace fracasar toda la sincronización si aparece al leer un certificado durante la sincronización con el CMS.

Las causas subyacentes no se pierden. DAT_MANAGER_NO_ISSUABLE_CERTIFICATE y DAT_CMS_IMPORT_FAILED transmiten el origen mediante el encadenamiento de excepciones propio de cada lenguaje (cause / __cause__ / InnerException / Unwrap()).

C/C++ conserva también los valores enteros

Los valores enteros existentes de dat_error_t se mantienen por compatibilidad ABI, pero el código de texto es el que manda. La biblioteca ya no devuelve los valores antiguos, así que una comparación como err == DAT_ERROR_INVALID_DAT ya no es válida. Compara mediante dat_error_code(e).

C no dispone de encadenamiento de excepciones, así que la causa se consulta aparte con dat_manager_issuable_cause().