Correos Express · SSL · Odoo 19

Correos Express in Odoo: SSL CERTIFICATE_VERIFY_FAILED error against the test endpoint — the fix.

If you are integrating a Correos Express delivery carrier module and, when calling the www.test.cexpr.es test environment, Odoo blows up with an SSL certificate verification error, it is not your code. It is the certificate chain of the Correos Express staging host. Here is the real cause and how to fix it without weakening production.

It is not your moduleThe staging host serves an incomplete chain.
Do not disable verifyThere is a clean fix that does not weaken production.
Production validates fineenvio.correosexpress.com does present a complete chain.
SSL CERTIFICATE_VERIFY_FAILED error diagnosis in the Correos Express Odoo integration
www.test.cexpr.esIncomplete certificate chain: the intermediate is missing. Production validates fine.

The real cause: an incomplete certificate chain on the staging host

When you integrate Correos Express and see this error, the instinct is to go check your code. No need. The problem sits on the Correos Express side, not in the module.

While developing against the Correos Express test environment, the HTTPS request from Python (requests / urllib via Odoo's delivery carrier module) fails with a trace similar to this:

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)')))

The key phrase is unable to get local issuer certificate. It does not say the certificate is expired, nor that the host does not match, nor that the CA is untrusted. It says Python cannot build the chain up to a trusted root because it is missing a link in the middle: the intermediate certificate.

What your code does right

The module verifies the certificate (verify=True by default). That is correct, and it is what a serious connector should do. The browser, on the other hand, forgives incomplete chains because it caches intermediates; Python does not.

What the test host does wrong

www.test.cexpr.es presents in the TLS handshake only the server certificate, without attaching the intermediate that chains it to the root. The client is left unable to validate against the public CA bundle.

Why production does work

The production host, envio.correosexpress.com, serves the complete chain (server + intermediate). That is why the same code that fails in staging validates without touching anything in production. It confirms the problem is the chain, not the module.

Complete the chain instead of turning off verification

The temptation is to set verify=False and move on. Don't: you weaken ALL HTTPS calls made by that Odoo instance, production included. The correct fix is to give the client the missing intermediate, only for this carrier.

Quick check: confirm it is the chain

Point REQUESTS_CA_BUNDLE at a bundle that includes the intermediate and re-run the call. If it passes, it proves the issue is chain completeness, not the module.

Pin the missing intermediate

Get the intermediate certificate from the issuer's published chain and store it together with the root in a carrier-owned PEM bundle. Invent nothing: you use the official intermediate that the staging host forgets to serve.

Pass verify=<bundle> per carrier, not global

In the carrier call, use requests(..., verify=<bundle>) pointing at the Correos Express bundle (which already includes the intermediate). It only affects this carrier; production and every other integration keep verifying against the default CA bundle.

Document the why in the README

Write in the README that the bundle exists because the staging host serves an incomplete chain, and that production does not need it. That way the next person who touches the module does not "fix" it by removing it and break staging again.

In one sentence: do not touch the global verify and do not set verify=False. Build a per-carrier bundle with the Correos Express intermediate, pass it as verify in the test calls and document the reason. Staging validates, production stays intact and the module keeps the TLS verification it should have.

We have already been through this staging certificate

We maintain a Correos Express connector for Odoo 19 and we have hit exactly this behaviour with the test certificate. It is no mystery to us: we have the working bundle setup solved and documented. We sell no smoke: we are a developer in Barcelona, the module is maintained for Odoo 19 and support is direct, with no reseller in between.

19maintained for Odoo 19
BCNdevelopment in Barcelona
1:1direct support

The connector and the certificate fix, together

You can grab the Correos Express connector from the App Store and apply the bundle setup yourself, or ask us to leave it working on your instance. If you also handle other carriers or marketplaces, we also maintain the MRW connector and marketplace connectors (Mirakl and derivatives), with the same technical criteria.

Connector on the App StoreCustom development

If this error brought you here, this also interests you

We connect this technical page with the rest of the FlexigoTech connectors and services catalog.

FAQ about the Correos Express SSL error

Is the CERTIFICATE_VERIFY_FAILED error a bug in the Odoo module?

No. The module does the right thing by verifying the certificate. The problem is on the Correos Express test host (www.test.cexpr.es), which serves an incomplete certificate chain: the intermediate is missing, so it does not validate against the public CA bundle. The production host (envio.correosexpress.com) validates without issues.

Isn't it faster to just set verify=False and disable SSL verification?

Not recommended. Disabling verify globally weakens ALL HTTPS calls made by that Odoo instance, production included, and exposes you to man-in-the-middle attacks. The correct fix is to pass verify pointing at your own bundle that includes the Correos Express intermediate, only for that carrier, without touching anything else.

How do I confirm it is a chain problem and not the module?

Point REQUESTS_CA_BUNDLE at a bundle that includes the missing intermediate and re-run the call. If verification passes, it confirms the problem is chain completeness on the staging host, not the module code.

Does FlexigoTech maintain a Correos Express connector for Odoo 19?

Yes. We maintain a Correos Express connector for Odoo 19 published on the App Store, and we have already resolved this staging certificate behaviour. We offer the working bundle setup and direct support with the developer, with no reseller in between.

Stuck with the Correos Express staging certificate?

We leave the bundle working on your instance, or hand you the Correos Express connector for Odoo 19 with the problem already solved. Direct support, no reseller in between.

Talk to FlexigoTechView the connector on the App Store