OpenBB-finance/OpenBB · error · OpenBBError

Failed to parse XML response

Error message

Failed to parse XML response: {url} -> {e}

What it means

After a successful HTTP 200, fetch_data parses the body with defusedxml; any parse failure (malformed XML, empty body, HTML error page served as 200) is wrapped in OpenBBError with the URL and parser exception.

Solutions

  1. Fetch the URL manually (same headers, incl. User-Agent) and inspect what is actually returned.
  2. Retry — truncation and transient bad payloads usually resolve.
  3. Report to OpenBB if the payload is well-formed XML that this parser rejects, including the URL.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    df = qb.fetch_data(url)
except OpenBBError as e:
    if 'Failed to parse XML' in str(e):
        inspect_raw_response(url, headers=imf_headers())  # see what the server really sent
        time.sleep(5)
        df = qb.fetch_data(url)
    else:
        raise

Prevention

When it happens

Trigger: api.imf.org returning HTML/text (WAF block page, maintenance notice) with status 200, truncated responses on interrupted connections, or payloads using an encoding defusedxml cannot decode.

Common situations: Corporate proxies rewriting responses, rare server-side serialization bugs, or bot-mitigation pages served to scripted clients.

Understand the failure class

Related errors


AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14). Data as JSON: /api/errors/f9f4f37841e166f8. Report an issue: GitHub.

Appendix: source

Thrown at openbb_platform/providers/imf/openbb_imf/utils/query_builder.py:374

        response = None

        try:
            response = make_request(url, headers=headers)
            response.raise_for_status()
            xml_content = response.text
        except RequestException as e:
            res_content = response.text if response else ""
            raise OpenBBError(
                f"An error occurred during the HTTP request: {url} -> {e} -> {res_content}"
            ) from e

        # Parse XML
        try:
            import defusedxml.ElementTree as DefusedET

            root = DefusedET.fromstring(xml_content)
        except Exception as e:  # pylint: disable=broad-except
            raise OpenBBError(f"Failed to parse XML response: {url} -> {e}") from e

        # Define namespaces used in IMF SDMX responses
        namespaces = {
            "message": "http://www.sdmx.org/resources/sdmxml/schemas/v3_0/message",
            "ss": "http://www.sdmx.org/resources/sdmxml/schemas/v3_0/data/structurespecific",
            "common": "http://www.sdmx.org/resources/sdmxml/schemas/v3_0/common",
        }

        # Find all Series elements
        dataset = root.find(".//message:DataSet", namespaces)
        if dataset is None:
            # Try without namespace prefix
            dataset = root.find(".//DataSet")
        if dataset is None:
            # Try with ss namespace
            dataset = root.find(".//ss:DataSet", namespaces)
        if dataset is None:
            raise OpenBBError(

View on GitHub (pinned to 3e071fcc2c)