odoo/odoo · error · UserError

Failed to connect to Odoo Peppol Proxy.

Error message

Failed to connect to Odoo Peppol Proxy.

What it means

UserError from PeppolIAPConnector.request_public_http (peppol_iap_connector.py:41): the requests call to the Peppol proxy endpoint failed at the transport level (DNS failure, connection refused, TLS error, timeout after TIMEOUT=10s, non-JSON response, or an HTTP error status whose body has no 'code' key). With no structured error payload to surface, Odoo raises the generic 'Failed to connect to Odoo Peppol Proxy.' and logs details at DEBUG level.

Source

Thrown at addons/account_peppol/tools/peppol_iap_connector.py:41

        self.env = company.env
        proxy_mode = company._get_peppol_edi_mode()
        assert proxy_mode in ('prod', 'test')
        self.proxy_mode = proxy_mode
        self.base_url = PEPPOL_PROXY_URLS[proxy_mode]

    def request_public_http(self, method, endpoint, data=None, params=None):
        headers = {'Content-Type': 'application/json'}
        url = urljoin(self.base_url, endpoint)
        response_vals = {}
        try:
            response = requests.request(method, url, json=data, params=params, timeout=TIMEOUT, headers=headers)
            response_vals = response.json()
            response.raise_for_status()
        except requests.exceptions.RequestException as e:
            if response_vals and 'code' in response_vals:
                raise UserError(get_peppol_error_message(self.env, response_vals))
            _logger.debug("Failed to connect to Odoo Peppol Proxy %s, %s", endpoint, e)
            raise UserError(self.env._("Failed to connect to Odoo Peppol Proxy."))
        return response_vals

    def can_connect(self, *, peppol_identifier, db_uuid, callback_url, connect_token, contact_email=None, webhook_url=None):
        return self.request_public_http('GET', '/api/peppol/2/can_connect', params={
            'dbuuid': db_uuid,
            'peppol_identifier': peppol_identifier,
            'callback_url': callback_url,
            'connect_token': connect_token,
            'contact_email': contact_email,
            'webhook_url': webhook_url,
        })

    def create_connection(self, *, peppol_identifier, db_uuid, public_key, auth_token=None, **company_details):
        params = {
            'peppol_identifier': peppol_identifier,
            'dbuuid': db_uuid,
            'company_id': self.company.id,
            'public_key': public_key,

View on GitHub (pinned to 1e661df964)

Solutions

  1. From the Odoo host, verify connectivity: curl -v https://peppol.api.odoo.com (and the test URL if in test mode).
  2. Open outbound HTTPS (443) to peppol.api.odoo.com / peppol.test.odoo.com in firewall/proxy rules; configure HTTP(S)_PROXY for the Odoo process if a corporate proxy is required.
  3. Retry after transient failures — the failure is transport-level, and registration can simply be re-attempted.
  4. Enable debug logging for the 'odoo.addons.account_peppol' logger to see the underlying exception ('Failed to connect to Odoo Peppol Proxy %s, %s' is logged at DEBUG).

Example fix

# shell diagnosis
# before: UserError 'Failed to connect to Odoo Peppol Proxy.'
curl -v --max-time 10 https://peppol.api.odoo.com/api/peppol/2/can_connect
Defensive patterns

Strategy: retry

Validate before calling

import socket
from urllib.parse import urlparse

def proxy_reachable(base_url, timeout=5):
    host = urlparse(base_url).hostname
    try:
        socket.create_connection((host, 443), timeout=timeout).close()
        return True
    except OSError:
        return False

if not proxy_reachable(connector.base_url):
    return defer_with_warning('Peppol proxy unreachable; will retry later')

Try / catch

for attempt in range(3):
    try:
        return connector.request_public_http(method, endpoint, params=params)
    except UserError as e:
        if 'Failed to connect' not in str(e) or attempt == 2:
            raise

Prevention

When it happens

Trigger: Any request_public_http call (can_connect during registration/verification, or other public endpoints) when the server cannot be reached or responds unparseably: network outage, firewall blocking peppol.api.odoo.com/peppol.test.odoo.com, corporate proxy/DNS misconfig, slow response exceeding the 10-second timeout, or the proxy returning an HTML error page.

Common situations: On-premise servers behind restrictive firewalls; Docker containers without outbound internet; self-hosted setups with broken DNS; transient proxy downtime; responses >10s (slow networks) hitting requests timeout; captive portals in datacenters.

Related errors


AI-assisted analysis of odoo/odoo@1e661df964 (2026-08-15). Data as JSON: /api/errors/742fdf8ec863d56c. Report an issue: GitHub.