{"record":{"id":"954732675e8184e6","repo":"django/django","slug":"invalid-data-source-file-s","errorCode":null,"errorMessage":"Invalid data source file \"%s\"","messagePattern":"Invalid data source file \"(.+?)\"","errorType":"exception","errorClass":"GDALException","httpStatus":null,"severity":"error","filePath":"django/contrib/gis/gdal/datasource.py","lineNumber":90,"sourceCode":"                )\n            except GDALException:\n                # Making the error message more clear rather than something\n                # like \"Invalid pointer returned from OGROpen\".\n                raise GDALException('Could not open the datasource at \"%s\"' % ds_input)\n        elif isinstance(ds_input, self.ptr_type) and isinstance(\n            ds_driver, Driver.ptr_type\n        ):\n            ds = ds_input\n        else:\n            raise GDALException(\"Invalid data source input type: %s\" % type(ds_input))\n\n        if ds:\n            self.ptr = ds\n            driver = capi.get_dataset_driver(ds)\n            self.driver = Driver(driver)\n        else:\n            # Raise an exception if the returned pointer is NULL\n            raise GDALException('Invalid data source file \"%s\"' % ds_input)\n\n    def __getitem__(self, index):\n        \"Allows use of the index [] operator to get a layer at the index.\"\n        if isinstance(index, str):\n            try:\n                layer = capi.get_layer_by_name(self.ptr, force_bytes(index))\n            except GDALException:\n                raise IndexError(\"Invalid OGR layer name given: %s.\" % index)\n        elif isinstance(index, int):\n            if 0 <= index < self.layer_count:\n                layer = capi.get_layer(self._ptr, index)\n            else:\n                raise IndexError(\n                    \"Index out of range when accessing layers in a datasource: %s.\"\n                    % index\n                )\n        else:\n            raise TypeError(\"Invalid index type: %s\" % type(index))","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/django/django/blob/ae25a40be07e8a749edf526df37c93e59d4a22c9/django/contrib/gis/gdal/datasource.py#L72-L108","documentation":"Raised as GDALException by DataSource.__init__ when GDALOpenEx returns a NULL pointer (the open call succeeded at the C level but produced no dataset). The check at datasource.py:84-90 distinguishes this from the caught-exception case: GDAL accepted the call but could not build a dataset, typically because the file is empty or unrecognized after driver probing.","triggerScenarios":"DataSource('empty.txt') where no driver claims the file; a zero-byte .geojson; a path to a directory that is not a valid multifile dataset; a file whose header does not match any registered driver.","commonSituations":"Uploading an empty/truncated file; pointing at a stub file created by touch; GDAL driver not registered for that extension; race condition where the file is still being written.","solutions":["Confirm the file is non-empty and has the correct magic bytes / extension.","Open with ogrinfo <file> outside Django to see the driver-level diagnostic.","Wait for the file to finish writing before opening, or open from a finalized path."],"exampleFix":"// before\nds = DataSource('partial.geojson')  # still being written\n// after\n# wait for write completion, validate size, then:\nds = DataSource('partial.geojson')","handlingStrategy":"validation","validationCode":"import os\ndef validate_dataset_file(path):\n    if os.path.getsize(path) == 0:\n        raise ValueError(f'{path} is empty; GDAL returned NULL')\n    return path","typeGuard":"def is_nonempty_file(p):\n    return isinstance(p, (str, Path)) and os.path.exists(p) and os.path.getsize(p) > 0","tryCatchPattern":"from django.contrib.gis.gdal import GDALException\ntry:\n    ds = DataSource(path)\nexcept GDALException as e:\n    if 'Invalid data source file' in str(e):\n        log.error('GDAL returned NULL for %s (size=%d)', path, os.path.getsize(path))","preventionTips":["Reject zero-byte uploads before they reach DataSource.","Validate file completeness (write temp + rename pattern) before opening."],"tags":["gis","gdal","datasource","io"],"analyzedSha":"ae25a40be07e8a749edf526df37c93e59d4a22c9","analyzedAt":"2026-08-06T21:46:51.801Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}