getredash/redash · error · Exception

Redash failed to parse the results it got from Elasticsearch

Error message

Redash failed to parse the results it got from Elasticsearch.

What it means

Elasticsearch runner's _parse_results raises this when the response matches neither the aggregation branch nor the hits branch it can tabulate — Redash received a response but its columns/rows extraction found nothing parseable (the else of the dispatch).

Source

Thrown at redash/query_runner/elasticsearch.py:322

                for field in result_fields:
                    add_column_if_needed(mappings, field, field, result_columns, result_columns_index)

            for h in raw_result["hits"]["hits"]:
                row = {}

                column_name = "_source" if "_source" in h else "fields"
                for column in h[column_name]:
                    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

View on GitHub (pinned to ca79fe988d)

Solutions

  1. Switch the query to explicit JSON/DSL mode with an _source field list
  2. Test the same query with curl against _search and inspect the response structure
  3. Upgrade Redash to a runner version supporting your Elasticsearch major version
  4. Restrict the query to fields that exist per the index mapping

Example fix

# before
{"query": {"match_all": {}}}

# after
{"query": {"match_all": {}}, "_source": ["field1", "field2"]}
Defensive patterns

Strategy: fallback

Validate before calling

import requests
r = requests.post(f'{server}/{index}/_search', auth=auth, json={'query': {'match_all': {}}, 'size': 1})
body = r.json()
assert 'hits' in body or 'aggregations' in body, f'unparseable shape: {list(body)}'

Type guard

def has_parseable_es_shape(body: dict) -> bool:
    return isinstance(body, dict) and ('aggregations' in body or 'hits' in body)

Try / catch

try:
    data, err = es_runner.run_query(q, u)
except Exception as e:
    if 'failed to parse the results' in str(e):
        data, err = es_runner.run_query(to_dsl_query_with_source(q), u)  # fallback to explicit DSL

Prevention

When it happens

Trigger: Querying Elasticsearch in simple-query mode where the response contains neither aggregations nor standard hits/_source/fields — e.g. unexpected top-level keys or a field layout the runner doesn't recognize.

Common situations: Elasticsearch 7→8 response-format differences, unmapped fields, or query DSL producing an unanticipated structure.

Understand the failure class

Related errors


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