Describe the bug
The default CRS resolution path silently writes malformed input into the user-defined citation field.
_wkt_to_epsg returns None and emits a GeoTIFFFallbackWarning when pyproj is missing or the input cannot be parsed. The writer then stores the original string as wkt_fallback at _writers/eager.py:481 and :499. The geokey emitter at _geotags.py:1100 warns that many readers will lose the CRS, but it still writes the verbatim bytes into GTCitationGeoKey.
A caller who passes to_geotiff(..., crs="EPSG:4326") on a host without pyproj ends up with the literal string "EPSG:4326" in the citation field. That is not a WKT, and most non-GDAL readers drop the projection entirely. A caller who passes a malformed PROJ string lands the same garbage in the file.
For a foundational I/O module this is too permissive. Round-trip safety is part of the contract.
Expected behavior
By default, when pyproj is available and parsing fails, raise instead of warning. When pyproj is missing and the supplied string is not a recognised WKT (no PROJCS / GEOGCS / PROJCRS / GEOGCRS / COMPD_CS / COMPOUNDCRS root), refuse to write a citation-only file. Callers who explicitly want the citation-only output opt in.
Proposed fix
- Add an
allow_unparseable_crs kwarg to to_geotiff / write_geotiff_gpu / write_vrt. Default False.
- When
False and the resolution path lands wkt_fallback, raise ValueError with a message naming the offending string and pointing at the opt-in.
- When
True, keep the existing warning + citation write.
- Keep the existing
XRSPATIAL_GEOTIFF_STRICT=1 env path consistent so strict mode also exercises the new default.
Additional context
Surfaced by an external review of the geotiff module. The existing XRSPATIAL_GEOTIFF_STRICT env var already supports re-raising the pyproj exception. This issue is about flipping the default and adding a per-call opt-in.
Describe the bug
The default CRS resolution path silently writes malformed input into the user-defined citation field.
_wkt_to_epsgreturnsNoneand emits aGeoTIFFFallbackWarningwhen pyproj is missing or the input cannot be parsed. The writer then stores the original string aswkt_fallbackat_writers/eager.py:481and:499. The geokey emitter at_geotags.py:1100warns that many readers will lose the CRS, but it still writes the verbatim bytes intoGTCitationGeoKey.A caller who passes
to_geotiff(..., crs="EPSG:4326")on a host without pyproj ends up with the literal string"EPSG:4326"in the citation field. That is not a WKT, and most non-GDAL readers drop the projection entirely. A caller who passes a malformed PROJ string lands the same garbage in the file.For a foundational I/O module this is too permissive. Round-trip safety is part of the contract.
Expected behavior
By default, when pyproj is available and parsing fails, raise instead of warning. When pyproj is missing and the supplied string is not a recognised WKT (no
PROJCS/GEOGCS/PROJCRS/GEOGCRS/COMPD_CS/COMPOUNDCRSroot), refuse to write a citation-only file. Callers who explicitly want the citation-only output opt in.Proposed fix
allow_unparseable_crskwarg toto_geotiff/write_geotiff_gpu/write_vrt. DefaultFalse.Falseand the resolution path landswkt_fallback, raiseValueErrorwith a message naming the offending string and pointing at the opt-in.True, keep the existing warning + citation write.XRSPATIAL_GEOTIFF_STRICT=1env path consistent so strict mode also exercises the new default.Additional context
Surfaced by an external review of the geotiff module. The existing
XRSPATIAL_GEOTIFF_STRICTenv var already supports re-raising the pyproj exception. This issue is about flipping the default and adding a per-call opt-in.