OpenBB-finance/OpenBB · error · OpenBBError
Failed to parse XML response: {url} -> {e}
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.
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)
Solutions
- Fetch the URL manually (same headers, incl. User-Agent) and inspect what is actually returned.
- Retry — truncation and transient bad payloads usually resolve.
- 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
- Ensure corporate proxies do not rewrite api.imf.org responses.
- Retry once on parse failure — truncated/odd 200 payloads are usually transient.
- Keep the custom User-Agent header; some WAFs serve HTML to generic agents.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Error fetching data: {e}
- Invalid JSON response from ECB
- Unexpected response format. Expected a dictionary, got {type
- {str(e) or 'FRED request failed ({type(e).__name__}).'}
- Failed to fetch data: {response.status}
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/f9f4f37841e166f8.
Report an issue: GitHub.