apache/superset · error · DatabaseUploadFailed

Not a valid ZIP file

Error message

Not a valid ZIP file

What it means

DatabaseUploadFailed ('Not a valid ZIP file') raised in ColumnarReader._yield_files when the uploaded filename ends in .zip but zipfile.is_zipfile(file) returns False — the stream does not start with a valid ZIP End-of-Central-Directory / local file header signature.

Source

Thrown at superset/commands/database/uploaders/columnar_reader.py:91

        except Exception as ex:
            raise DatabaseUploadFailed(_("Error reading Columnar file")) from ex

    @staticmethod
    def _yield_files(file: FileStorage) -> Generator[IO[bytes], None, None]:
        """
        Yields files from the provided file. If the file is a zip file, it yields each
        file within the zip file. If it's a single file, it yields the file itself.

        :param file: The file to yield files from.
        :return: A generator that yields files.
        """
        file_suffix = Path(file.filename).suffix
        if not file_suffix:
            raise DatabaseUploadFailed(_("Unexpected no file extension found"))
        file_suffix = file_suffix[1:]  # remove the dot
        if file_suffix == "zip":
            if not is_zipfile(file):
                raise DatabaseUploadFailed(_("Not a valid ZIP file"))
            try:
                with ZipFile(file) as zip_file:
                    # guard against decompression bombs before reading entries,
                    # mirroring the importer path
                    try:
                        check_is_safe_zip(zip_file)
                    except SupersetException as ex:
                        raise DatabaseUploadFailed(str(ex)) from ex
                    # check if all file types are of the same extension
                    file_suffixes = {Path(name).suffix for name in zip_file.namelist()}
                    if len(file_suffixes) > 1:
                        raise DatabaseUploadFailed(
                            _("ZIP file contains multiple file types")
                        )
                    for filename in zip_file.namelist():
                        with zip_file.open(filename) as file_in_zip:
                            yield BytesIO(file_in_zip.read())
            except BadZipfile as ex:

View on GitHub (pinned to f4587218dd)

Solutions

  1. Verify the file locally: 'file data.zip' should report 'Zip archive data'
  2. Re-download/re-export the archive if it was truncated or is actually an error payload
  3. If the payload is a single Parquet file, rename it to .parquet instead of .zip

Example fix

# shell check
file upload.zip   # 'Zip archive data' -> ok; anything else -> not a zip
Defensive patterns

Strategy: validation

Validate before calling

import zipfile

def is_valid_zip(fh) -> bool:
    fh.seek(0)
    return zipfile.is_zipfile(fh)

Prevention

When it happens

Trigger: Uploading a file named *.zip that is not a ZIP archive: a renamed Parquet or CSV file, a truncated download, an S3 pre-signed response saved as .zip, or an HTML error page saved with a .zip extension.

Common situations: Users renaming files to force the wrong reader; interrupted downloads (ZIP central directory is at the end and missing when truncated); proxy/CDN error responses (XML AccessDenied from S3) saved as .zip.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/2dc39fda9cf63a36. Report an issue: GitHub.