Bug description

Apache Superset Version: 4.1.2 Deployment: Dockerized, with two VMs (one for Superset web UI, one for Celery workers) Domain: Both services under the same domain

Issue

When embedding a dashboard via iframe, queries using a single Jinja filter work correctly. However, when using multiple Jinja parameters, Superset fails to retrieve cached results.

Embedded dashboards with multiple Jinja filters cannot load correct data. Breaks embedding functionality in production scenarios where filtering is critical.

Image

Request/Response Sequence

Embedded Dashboard Request

GET /embedded/<uuid>?CAR_IDS=...&CHASSIS_IDS=...&START_DATE=2025-07-01&END_DATE=2025-08-31

  • Returns 200 OK.
  • Dashboard renders, initiating async queries.

Async Event Polling

GET /api/v1/async_event/

  • Response 200 OK β†’ status: done, includes a result_url to cached data.

Data Retrieval Request

GET /api/v1/chart/data/<cache_key>

  • Expected: Retrieve cached result from Redis.
  • Actual: 422 Unprocessable Entity
  • {"message": "Error loading data from cache"}

Debugging Performed

  • Verified Celery worker writes results successfully to Redis.
  • Inspected Redis with Redis Commander: cache key exists.
  • Web UI fails to load the cached payload β†’ mismatch between write/read phases.
  • Confirmed both services use the same Redis instance and DB in superset_config.py.
  • Observed the error only when multiple URL parameters (comma-separated) are passed.

Jinja Template Context

SELECT * FROM v_tx_facts_metadata
WHERE car_ids && string_to_array('{{ url_param("CAR_IDS") }}', ',')::varchar[]
AND chassis_ids && string_to_array('{{ url_param("CHASSIS_IDS") }}', ',')::varchar[]
AND date BETWEEN '{{ url_param("START_DATE") }}' AND '{{ url_param("END_DATE") }}'

Attempted Workaround

Used url_param('param', add_to_cache_keys=False) to exclude filters from cache keys.

Result: Eliminated the 422 error but produced incorrect results, as Superset reused the base cached query regardless of filter values.

Additionally, tested disabling GLOBAL_ASYNC_QUERIES. This allowed the dashboard to work with multiple parameters, but it bypassed the Celery workers entirely, forcing synchronous execution. This resolves the cache mismatch but sacrifices async processing and scalability.

Root Cause (based on analysis and related GitHub issues #24171, #31492, PR #25549)

  • Cache key serialization/encoding issues with multiple parameters.
  • Inconsistent cache key generation between Celery worker (write) and web UI (read).
  • Issue specific to embedded dashboards with async queries and Jinja filters.

Expected Behavior

Multi-parameter Jinja queries should correctly generate and retrieve cache keys.

Filters applied via URL parameters should not break async query caching.

Screenshots/recordings

No response

Superset version

master / latest-dev

Python version

3.9

Node version

16

Browser

Chrome

Additional context

No response

Checklist

  • [ ] I have searched Superset docs and Slack and didn't find a solution to my problem.
  • [ ] I have searched the GitHub issue tracker and didn't find a similar bug report.
  • [ ] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.

Comment From: dosubot[bot]

This is a known, unresolved issue in Superset 4.1.2 (and master): async query cache retrieval fails with multi-parameter Jinja filters (like multiple url_param values) in embedded dashboards. The root cause is inconsistent serialization of URL parameters between the Celery worker (write phase) and the web UI (read phase)β€”for example, one side may serialize a list as a CSV string, while the other expects a list, causing cache key mismatches and 422 errors even though the cache key exists in Redis. This is not a Redis or Celery config problem, but a bug in how Superset serializes and hashes filter values for cache keys in async queries with Jinja templating [1].

Workarounds like setting add_to_cache_keys=False on url_param avoid the error but break filtering, since the cache key no longer reflects filter values. Disabling GLOBAL_ASYNC_QUERIES avoids the bug but sacrifices async processing and scalability [2]. Some users have reverted a deduplication change in get_extra_cache_keys (removing list(set(...))) as a local patch, but this is not a general solution and may have side effects [3].

There is no official fix or comprehensive workaround as of August 2025. The bug persists in the latest Superset versions. If you need async queries and multi-parameter Jinja filters in production, you may need to limit to single-parameter filters, avoid async queries, or monitor for upstream fixes. For reference, the relevant code paths are: superset/jinja_context.py (ExtraCache, url_param), superset/common/query_object.py (QueryObject.cache_key), superset/common/query_context_processor.py (QueryContextProcessor.query_cache_key), and superset/connectors/sqla/models.py (get_extra_cache_keys) [4].

If you want to explore a custom patch, the key is to ensure that URL parameters are serialized in a canonical way (e.g., always as a sorted, comma-separated string) in both the async job and the web UI before hashing for the cache key. Let me know if you want more details on where to apply such a patch.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report πŸ› | Other  Chat with Dosu Join Discord Share on X