getredash/redash · error · Exception
Failed to connect to Cloudflare D1: {str(e)}
Error message
Failed to connect to Cloudflare D1: {str(e)} What it means
D1 runner's _query wraps requests exceptions from the Cloudflare D1 HTTP API call into 'Failed to connect to Cloudflare D1: <e>'. Connection-level problems (DNS, TLS, refused, HTTP errors) before any JSON parsing.
Source
Thrown at redash/query_runner/d1.py:85
headers = {
"Authorization": f"Bearer {self.configuration.get('cf_token')}",
"Content-Type": "application/json",
}
body = {"sql": sql, "params": params or []}
try:
resp = session.post(self.configuration.get("cf_url"), headers=headers, data=json.dumps(body), timeout=30)
resp.raise_for_status()
data = resp.json()
# Expected: { "result": [ { "results": [...] } ] }
results = data.get("result", [])
if not results:
return []
return results[0].get("results", [])
except session.exceptions.RequestException as e:
raise Exception(f"Failed to connect to Cloudflare D1: {str(e)}")
except json.JSONDecodeError as e:
raise Exception(f"Invalid JSON response from D1: {str(e)}")
except KeyError as e:
raise Exception(f"Unexpected response format from D1: {str(e)}")
def run_query(self, query, user):
try:
rows = self._query(query)
if not rows:
return {"columns": [], "rows": []}, None
# Infer columns from first row
first_row = rows[0]
columns = []
for k, v in first_row.items():
# Get the Python type name and map it to Redash type
python_type = type(v).__name__
redash_type = TYPES_MAP.get(python_type, TYPE_STRING)View on GitHub (pinned to ca79fe988d)
Solutions
- Verify account_id and database_id against the Cloudflare dashboard
- curl the API from the Redash host to confirm egress and IDs
- Fix proxy/TLS settings if curl also fails
- Regenerate the API token if the message includes an auth-related HTTP error
Example fix
# before
{"account_id": "wrong-id", "database_id": "db", "api_token": "..."}
# after
{"account_id": "a1b2c3...", "database_id": "<uuid from D1 dashboard>", "api_token": "..."} Defensive patterns
Strategy: validation
Validate before calling
import requests
r = requests.get(f"https://api.cloudflare.com/client/v4/accounts/{account_id}", headers={"Authorization": f"Bearer {token}"}, timeout=5)
assert r.ok, 'fix account_id/token/network before querying' Try / catch
try:
rows = d1_runner._query(q)
except Exception as e:
if str(e).startswith('Failed to connect to Cloudflare D1'):
alert_network_or_ids(); rows = [] Prevention
- Verify account_id/database_id against the dashboard at provisioning time
- Allow-list api.cloudflare.com in egress firewalls
- Add a connectivity preflight to scheduled jobs
When it happens
Trigger: POSTing to /client/v4/accounts/.../d1/database/.../query when requests raises RequestException: bad account/database IDs in the URL, blocked egress, or an invalid API endpoint.
Common situations: Wrong account_id or database_id in configuration, egress firewall blocking api.cloudflare.com, proxy/TLS interception, or a typo'd API base URL.
Related errors
- Connection error to: {} {}.
- Couchbase connection error
- Connection error to: {url} {details}.
- Invalid JSON response from D1: {str(e)}
- Unexpected response format from D1: {str(e)}
AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28).
Data as JSON: /api/errors/a152b62d5489bf70.
Report an issue: GitHub.