Skip to content

CSV download fails with "_csv.Error: need to escape, but no escapechar set" when query results contain NUL bytes (\x00) #7758

Description

@weistom

Issue Summary

CSV download fails with HTTP 500 when query result rows contain a NUL byte (\x00, CHAR(0)) in string fields. The browser may save a .csv file whose content is a JSON error response instead of CSV data. Excel download for the same query result succeeds.

This occurs on Redash 25.8.0 (67a95e9) with Python 3.10 (self-hosted Docker). The failure is server-side; it is reproducible regardless of browser/OS.

Server log:

[ERROR][redash.app] Exception on /api/queries/43/results/xxxx.csv [GET]
...
File "/app/redash/serializers/query_result.py", line 98, in serialize_query_result_to_dsv
    writer.writerow(row)
_csv.Error: need to escape, but no escapechar set

Steps to Reproduce

  1. Ensure the database contains a string value with an embedded NUL byte, e.g.:
    SELECT id, address
    FROM users
    WHERE INSTR(address, CHAR(0)) > 0;
  2. Create and run a Redash query that returns the affected row(s).
  3. Click Download as CSV File → download fails (HTTP 500; JSON error may be saved as .csv).
  4. Click Download as Excel File for the same result → download succeeds.

Any other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?

This is a bug because CSV export should handle real-world string data safely. NULL bytes can exist in user-entered text stored in databases, and CSV download should not crash while Excel download works for the same data.

Expected: CSV download succeeds (values are escaped or sanitized).

Actual: CSV download raises _csv.Error: need to escape, but no escapechar set in serialize_query_result_to_dsv() because Python 3.10's csv.DictWriter cannot write fields containing \x00 with default settings. Excel export uses xlsxwriter and is unaffected.

Related upstream: pandas-dev/pandas#47871

Suggested fix: Sanitize string values in redash/serializers/query_result.py before writer.writerow(), e.g. value.replace("\x00", ""), or configure the CSV writer with an explicit escapechar.

Workaround: Download as Excel and convert to CSV; or in SQL use REPLACE(column, CHAR(0), '') (MySQL).

Technical details:

  • Redash Version: 25.8.0 (67a95e9)
  • Browser/OS: Chrome / macOS (issue is server-side; not browser-specific)
  • How did you install Redash: Docker (self-hosted)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions