{"record":{"id":"a152b62d5489bf70","repo":"getredash/redash","slug":"failed-to-connect-to-cloudflare-d1-str-e","errorCode":null,"errorMessage":"Failed to connect to Cloudflare D1: {str(e)}","messagePattern":"Failed to connect to Cloudflare D1: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"redash/query_runner/d1.py","lineNumber":85,"sourceCode":"        headers = {\n            \"Authorization\": f\"Bearer {self.configuration.get('cf_token')}\",\n            \"Content-Type\": \"application/json\",\n        }\n        body = {\"sql\": sql, \"params\": params or []}\n\n        try:\n            resp = session.post(self.configuration.get(\"cf_url\"), headers=headers, data=json.dumps(body), timeout=30)\n            resp.raise_for_status()\n            data = resp.json()\n\n            # Expected: { \"result\": [ { \"results\": [...] } ] }\n            results = data.get(\"result\", [])\n            if not results:\n                return []\n            return results[0].get(\"results\", [])\n\n        except session.exceptions.RequestException as e:\n            raise Exception(f\"Failed to connect to Cloudflare D1: {str(e)}\")\n        except json.JSONDecodeError as e:\n            raise Exception(f\"Invalid JSON response from D1: {str(e)}\")\n        except KeyError as e:\n            raise Exception(f\"Unexpected response format from D1: {str(e)}\")\n\n    def run_query(self, query, user):\n        try:\n            rows = self._query(query)\n            if not rows:\n                return {\"columns\": [], \"rows\": []}, None\n\n            # Infer columns from first row\n            first_row = rows[0]\n            columns = []\n            for k, v in first_row.items():\n                # Get the Python type name and map it to Redash type\n                python_type = type(v).__name__\n                redash_type = TYPES_MAP.get(python_type, TYPE_STRING)","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/query_runner/d1.py#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"Wrong account_id or database_id in configuration, egress firewall blocking api.cloudflare.com, proxy/TLS interception, or a typo'd API base URL.","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"],"exampleFix":"# before\n{\"account_id\": \"wrong-id\", \"database_id\": \"db\", \"api_token\": \"...\"}\n\n# after\n{\"account_id\": \"a1b2c3...\", \"database_id\": \"<uuid from D1 dashboard>\", \"api_token\": \"...\"}","handlingStrategy":"validation","validationCode":"import requests\nr = requests.get(f\"https://api.cloudflare.com/client/v4/accounts/{account_id}\", headers={\"Authorization\": f\"Bearer {token}\"}, timeout=5)\nassert r.ok, 'fix account_id/token/network before querying'","typeGuard":null,"tryCatchPattern":"try:\n    rows = d1_runner._query(q)\nexcept Exception as e:\n    if str(e).startswith('Failed to connect to Cloudflare D1'):\n        alert_network_or_ids(); rows = []","preventionTips":["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"],"tags":["redash","cloudflare-d1","network","http"],"backgroundTag":"connection-refused","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}