Correos Express · SSL · Odoo 19

Correos Express en Odoo: error SSL CERTIFICATE_VERIFY_FAILED contra el endpoint de pruebas — solución.

Si estás integrando un módulo delivery carrier de Correos Express y, al llamar al entorno de pruebas www.test.cexpr.es, Odoo revienta con un error SSL de verificación de certificado, no es tu código. Es la cadena de certificado del host de staging de Correos Express. Aquí te explicamos la causa real y cómo solucionarlo sin debilitar producción.

No es tu móduloEl host de staging sirve una cadena incompleta.
No desactives verifyHay una solución limpia sin debilitar producción.
Producción valida bienenvio.correosexpress.com sí presenta cadena completa.
Diagnóstico de error SSL CERTIFICATE_VERIFY_FAILED en integración Correos Express con Odoo
www.test.cexpr.esCadena de certificado incompleta: falta el intermedio. Producción valida sin problema.

La causa real: cadena de certificado incompleta en el host de staging

Cuando integras Correos Express y ves este error, el instinto es revisar tu código. No hace falta. El problema está del lado de Correos Express, no del módulo.

Mientras desarrollas contra el entorno de pruebas de Correos Express, la petición HTTPS de Python (requests / urllib vía el módulo delivery carrier de Odoo) falla con una traza similar a esta:

requests.exceptions.SSLError: HTTPSConnectionPool(host='www.test.cexpr.es', port=443):
  Max retries exceeded with url: /...
  (Caused by SSLError(SSLCertVerificationError(1,
  '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed:
   unable to get local issuer certificate (_ssl.c:1007)')))

La frase clave es unable to get local issuer certificate. No dice que el certificado esté caducado, ni que el host no coincida, ni que la CA no sea de confianza. Dice que Python no puede construir la cadena hasta una raíz de confianza porque le falta un eslabón por el medio: el certificado intermedio.

Qué hace bien tu código

El módulo verifica el certificado (verify=True por defecto). Eso es correcto y es lo que debe hacer un conector serio. El navegador, en cambio, perdona cadenas incompletas porque cachea intermedios; Python no.

Qué hace mal el host de pruebas

www.test.cexpr.es presenta en el handshake TLS solo el certificado de servidor, sin adjuntar el intermedio que lo encadena con la raíz. El cliente queda sin poder validar contra el bundle público de CAs.

Por qué producción sí funciona

El host de producción, envio.correosexpress.com, sirve la cadena completa (servidor + intermedio). Por eso el mismo código que falla en staging valida sin tocar nada en producción. Confirma que el problema es de cadena, no de módulo.

Completa la cadena en vez de apagar la verificación

La tentación es poner verify=False y seguir. No lo hagas: debilitas TODAS las llamadas HTTPS de esa instancia de Odoo, incluida producción. La solución correcta es darle al cliente el intermedio que falta, solo para este carrier.

Comprobación rápida: confirma que es la cadena

Apunta REQUESTS_CA_BUNDLE a un bundle que incluya el intermedio y relanza la llamada. Si pasa, queda probado que es completitud de cadena, no el módulo.

Fija (pin) el intermedio que falta

Obtén el certificado intermedio de la cadena publicada del emisor y guárdalo junto a la raíz en un bundle PEM propio del carrier. No inventes nada: usas el intermedio oficial que el host de staging se olvida de servir.

Pasa verify=<bundle> por carrier, no global

En la llamada del carrier, usa requests(..., verify=<bundle>) apuntando al bundle de Correos Express (que ya incluye el intermedio). Solo afecta a este carrier; producción y el resto de integraciones siguen verificando contra el bundle de CAs por defecto.

Documenta el porqué en el README

Deja escrito en el README que el bundle existe porque el host de staging sirve cadena incompleta, y que producción no lo necesita. Así el siguiente que toque el módulo no "arregla" quitándolo y rompe staging otra vez.

En una frase: no toques el verify global ni metas verify=False. Construye un bundle por carrier con el intermedio de Correos Express, pásalo como verify en las llamadas de pruebas y documenta el motivo. Staging valida, producción sigue intacta y el módulo mantiene la verificación TLS que debe tener.

Ya hemos pasado por este certificado de staging

Mantenemos un conector de Correos Express para Odoo 19 y nos hemos topado exactamente con este comportamiento del certificado de pruebas. No es un misterio para nosotros: tenemos el setup del bundle funcional resuelto y documentado. No vendemos humo: somos un desarrollador en Barcelona, el módulo está mantenido para Odoo 19 y el soporte es directo, sin reseller por medio.

19mantenido para Odoo 19
BCNdesarrollo en Barcelona
1:1soporte directo

El conector y la solución de certificado, juntos

Puedes coger el conector de Correos Express del App Store y aplicar tú mismo el setup del bundle, o pedirnos que te lo dejemos funcionando en tu instancia. Si además trabajas otros carriers o marketplaces, mantenemos también el conector de MRW y conectores de marketplace (Mirakl y derivados), con el mismo criterio técnico.

Conector en el App StoreDesarrollo a medida

Si has llegado por este error, esto también te interesa

Conectamos esta página técnica con el resto del catálogo de conectores y servicios de FlexigoTech.

Preguntas frecuentes sobre el error SSL de Correos Express

¿El error CERTIFICATE_VERIFY_FAILED es un fallo del módulo de Odoo?

No. El módulo hace lo correcto al verificar el certificado. El fallo está en el host de pruebas de Correos Express (www.test.cexpr.es), que sirve una cadena de certificado incompleta: falta el intermedio y por eso no valida contra el bundle de CAs públicas. El host de producción (envio.correosexpress.com) valida sin problemas.

¿No es más rápido poner verify=False y desactivar la verificación SSL?

No es recomendable. Desactivar verify globalmente debilita TODAS las llamadas HTTPS de esa instancia de Odoo, incluida producción, y te expone a man-in-the-middle. La solución correcta es pasar verify apuntando a un bundle propio que incluya el intermedio de Correos Express, solo para ese carrier, sin tocar el resto.

¿Cómo confirmo que es un problema de cadena y no del módulo?

Apunta REQUESTS_CA_BUNDLE a un bundle que incluya el intermedio que falta y vuelve a lanzar la llamada. Si la verificación pasa, queda confirmado que el problema es la completitud de la cadena del host de staging y no el código del módulo.

¿FlexigoTech mantiene un conector de Correos Express para Odoo 19?

Sí. Mantenemos un conector de Correos Express para Odoo 19 publicado en el App Store y ya hemos resuelto este comportamiento del certificado de staging. Ofrecemos el setup del bundle funcional y soporte directo con el desarrollador, sin reseller intermedio.

¿Atascado con el certificado de staging de Correos Express?

Te dejamos el bundle funcionando en tu instancia o te pasamos el conector de Correos Express para Odoo 19 con el problema ya resuelto. Soporte directo, sin reseller por medio.

Hablar con FlexigoTechVer el conector en el App Store