One call, many addresses: local files, /vsicurl/, ZARR: and NETCDF: syntax, vrt:// options, /vsizip/.
gdalxarray passes the string you give it to GDAL unchanged, so everything GDAL’s virtual file systems and connection strings can express is available without any code in gdalxarray. This page walks through the common ones using three days of real NOAA OISST v2.1 sea surface temperature kept with this repository, so it runs anywhere.
Data: NOAA 0.25-degree Daily Optimum Interpolation Sea Surface Temperature (OISST), Version 2.1; doi:10.25921/RE9P-PT57; licence: CC0-1.0; days 20250101, 20250102, 20250103. Built by scripts/fixtures/make_oisst.py; details in docs/fixtures/oisst/provenance.json.
Prefix or syntax
What it does
/vsicurl/<url>
HTTP(S) range requests
/vsis3/<bucket>/<key>, /vsigs/, /vsiaz/
object stores (anonymous with AWS_NO_SIGN_REQUEST=YES)
/vsizip/<zip>/<member>
a member of a zip, which can itself be remote
ZARR:"<store>":/<array>[:i:j]
one array of a Zarr store, optionally a 2D slice of it
NETCDF:"<file>":<var>
one variable of a netCDF as a classic raster
vrt://<path>?<options>
an inline VRT: resize, subset, assign a CRS, pick bands
The same store, three addresses
A local directory, the same directory with the explicit ZARR: prefix, and the same store over HTTPS (this repository on GitHub, at the commit that last changed it) all give the same Dataset:
opened = {k: xr.open_dataset(v, engine="gdalxarray") for k, v in addresses.items()}ref = opened["local"]["sst"].isel(time=1).values{k: bool(np.array_equal(d["sst"].isel(time=1).values, ref, equal_nan=True)) for k, d in opened.items()}
For a remote Zarr the ZARR: prefix is not optional. A web server has no directory listing to sniff, so a bare /vsicurl/.../store.zarr does not identify as anything:
RuntimeError HTTP response code: 404 - Failure writing output to destination, passed 14 returned 0
For the same reason, a Zarr v3 store meant to be read over HTTP needs consolidated metadata (a consolidated_metadata entry in its root zarr.json, which xarray writes with to_zarr(..., consolidated=True)). Without it the store still opens, but with no arrays in it, because there is no listing to find them by.
Over /vsicurl/, also set GDAL_DISABLE_READDIR_ON_OPEN=EMPTY_DIR so GDAL does not try to list what is really a web server. This site sets it for every page.
A 2D face of an N-D array
ZARR:"store":/array:i:j fixes the leading dimensions of an array to indices i, j, leaving a 2D raster that classic tools understand. Here sst is (time, zlev, lat, lon), and :2:0 picks the third day:
face = xr.open_dataset(f'ZARR:"{data(rel)}":/sst:2:0', engine="gdalxarray", multidim=False)face["band_data"].dims, face["band_data"].shape
(('band', 'y', 'x'), (1, 720, 1440))
The stored values are identical to the multidim read of the same day:
but the two models can disagree on the fill value. A Zarr v3 array has two places for one: the Zarr-level fill_value in its metadata, and a CF _FillValue among its attributes. Here is what xarray wrote for sst, OISST’s own packing being int16 with a -999 fill:
meta = data_json(f"{rel}/sst/zarr.json"){"zarr fill_value": meta["fill_value"], "CF _FillValue": meta["attributes"].get("_FillValue")}
{'zarr fill_value': 0, 'CF _FillValue': -999}
GDAL reports the Zarr-level value as the band or array nodata; gdalxarray’s multidim path prefers the CF attribute, and the classic path has only GDAL’s band value to go on:
So with mask-and-scale decoding on, the classic face masks 0 rather than -999: on this data, land cells (stored as -999) come through as -9.99 degrees, and real water at exactly 0 degrees is masked. Pass mask_and_scale=False and decode yourself, or prefer the multidim read, for stores written this way.
A netCDF variable, either way
One of the daily OISST netCDF files, exactly as NOAA publishes it, can be opened as a multidimensional dataset, or one variable as a classic raster with NETCDF::
The two models differ in one way worth knowing: classic mode presents the raster north-up (GDAL flips a south-up netCDF to give a conventional geotransform), while multidim keeps the storage order.