getredash/redash · error · Exception

Failed to execute query. Return Code: {0} Reason: {1}

Error message

Failed to execute query. Return Code: {0}   Reason: {1}

What it means

Elasticsearch runner's test_connection GETs /_cluster/health and on requests.HTTPError (a 4xx/5xx was returned) re-raises with the status code and body text. Transport succeeded but the server rejected the request.

Source

Thrown at redash/query_runner/elasticsearch.py:330

                    if result_fields and column not in result_fields_index:
                        continue

                    add_column_if_needed(mappings, column, column, result_columns, result_columns_index)

                    value = h[column_name][column]
                    row[column] = value[0] if isinstance(value, list) and len(value) == 1 else value

                result_rows.append(row)
        else:
            raise Exception("Redash failed to parse the results it got from Elasticsearch.")

    def test_connection(self):
        try:
            r = requests.get("{0}/_cluster/health".format(self.server_url), auth=self.auth)
            r.raise_for_status()
        except requests.HTTPError as e:
            logger.exception(e)
            raise Exception("Failed to execute query. Return Code: {0}   Reason: {1}".format(r.status_code, r.text))
        except requests.exceptions.RequestException as e:
            logger.exception(e)
            raise Exception("Connection refused")


class Kibana(BaseElasticSearch):
    @classmethod
    def enabled(cls):
        return True

    def _execute_simple_query(self, url, auth, _from, mappings, result_fields, result_columns, result_rows):
        url += "&from={0}".format(_from)
        r = requests.get(url, auth=self.auth)
        r.raise_for_status()

        raw_result = r.json()

        self._parse_results(mappings, result_fields, raw_result, result_columns, result_rows)

View on GitHub (pinned to ca79fe988d)

Solutions

  1. curl -u user:pass https://host/_cluster/health and match the status: 401 → fix credentials, 403 → security role, 404 → fix URL/base path
  2. Correct the server URL including any path prefix
  3. Wait for ES to come up (503) and retest
  4. Grant the user the cluster monitor privilege for the health endpoint

Example fix

# before
{"server": "https://es.example.com/old-prefix", "basic_auth_user": "u", "basic_auth_password": "wrong"}

# after
{"server": "https://es.example.com:9200", "basic_auth_user": "u", "basic_auth_password": "correct"}
Defensive patterns

Strategy: validation

Validate before calling

import requests
r = requests.get(f'{server}/_cluster/health', auth=auth, timeout=5)
assert r.status_code == 200, f'{r.status_code}: {r.text[:200]}'

Try / catch

try:
    runner.test_connection()
except Exception as e:
    if 'Return Code:' in str(e):
        code, _, reason = str(e).partition('Return Code:')[2].partition('Reason:')
        route(code.strip())  # 401 creds, 403 security, 404 URL, 503 wait

Prevention

When it happens

Trigger: Clicking Test Connection when /_cluster/health returns 401 (bad basic-auth), 403 (security restrictions), 404 (wrong URL/base path), or 503 (ES still starting).

Common situations: Wrong X-Pack credentials, URL with a missing or wrong path prefix, a gateway blocking the health endpoint, or the cluster still booting.

Related errors


AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28). Data as JSON: /api/errors/38ae8a73deb53b94. Report an issue: GitHub.