Solution skill
Diagnose and fix xr.open_mfdataset combine failures (MergeError, compat, defaults)
Complete solution
Diagnose xr.open_mfdataset failures from the error message and file layout: classify nested vs by_coords vs merge, resolve MergeError 'conflicting values' with compat/compat_attrs/preprocess, and pin data_vars/compat explicitly against the 2025.x default-change FutureWarnings.
Diagnose and fix open_mfdataset combine failures
TL;DR
Diagnose xr.openmfdataset failures from the error message and file layout: classify nested vs bycoords vs merge, resolve MergeError 'conflicting values' with compat/compatattrs/preprocess, and pin datavars/compat explicitly against the 2025.x default-change FutureWarnings.
Use this when xr.open_mfdataset raises MergeError: conflicting values for variable '...' on objects to be combined, silently drops variables you expected, or emits FutureWarnings about data_vars / compat defaults. Almost every failure is one of a small set of combine misconfigurations, and this procedure identifies which one from the error message and your file layout before you change anything.
When not to use this skill: a single file opens fine with xr.open_dataset (no combine involved); the error is a missing file or permission problem rather than a merge conflict; you are combining in-memory datasets (use xr.merge/xr.concat directly, not open_mfdataset).
1. Read the exact error or warning
The two dominant failure signatures:
xarray.core.merge.MergeError: conflicting values for variable 'lon_bnds' on
objects to be combined. You can skip this check by specifying compat='override'.FutureWarning: In a future version of xarray the default value for data_vars
will change from data_vars='all' to data_vars='minimal'. ... To opt in to new
defaults and get rid of these warnings now use
`set_options(use_new_combine_kwarg_defaults=True)` or set data_vars explicitly.A parallel FutureWarning exists for compat ('no_conflicts' → 'override'). These warnings are real breaking-change previews: pick your side explicitly now rather than letting a future xarray release change your results silently.
2. Classify the file layout first
Your choice of combine follows the geometry of the file set, not the error:
- Time slices along an existing dimension (each file holds
time: 365for a
different year, same lat/lon grid): use combine='nested' with an explicit concat_dim:
ds = xr.open_mfdataset(
"model_*.nc",
combine="nested",
concat_dim="time",
data_vars="minimal", # only concat variables that actually span time
coords="minimal", # same for coordinates
)data_vars='minimal' concatenates only variables that contain the concat dimension. Everything else (static fields, bounds variables) goes through the compat check instead of being needlessly concatenated. This is the forward-compatible choice for time-slice archives.
- Files that tile different coordinate values (different lat/lon boxes, or
irregularly named files whose order you don't trust): use combine='by_coords' (this is open_mfdataset's default). xarray orders the files by their coordinate values, ignoring filename order.
- Neither (files overlap in coordinates but hold different variables, e.g.
one file per variable): that is a merge job, not a combine job. Open each with xr.open_dataset and use xr.merge instead.
Note: passing concat_dim together with combine='by_coords' is an error (combine_by_coords takes no concat_dim), and has been a hard error rather than a warning since xarray 2023.11.0.
3. Classify the conflicting variable
The MergeError names one variable. Open two files individually and compare:
a = xr.open_dataset("file_0000.nc")
b = xr.open_dataset("file_0001.nc")
print(a["lon_bnds"].identical(b["lon_bnds"])) # False → the values genuinely differ
print(a["lon_bnds"].values.ravel()[:5], b["lon_bnds"].values.ravel()[:5])- A genuinely static field that differs trivially between files (bounds
variables like lon_bnds/lat_bnds, orography, surface_altitude recomputed with slightly different rounding): the equality check is stricter than you need. Pass compat='override' — xarray takes the first file's value and moves on. The error message itself suggests this.
- A coordinate that differs because files genuinely cover different tiles:
you want combine='by_coords', not compat='override' — overriding would silently keep the wrong grid for later files.
- A data variable that should have been concatenated but wasn't: you passed
(or defaulted to) data_vars='minimal' and the variable doesn't span the concat dim, or the concat dim name differs between files (e.g. Time vs time). Fix the dim, don't relax compat.
- Global attributes conflicting: those are governed by
combine_attrs
('drop' | 'identical' | 'no_conflicts' | 'override'), not compat. open_mfdataset reads global attrs from the first file by default; override with the attrs_file argument if a specific file is authoritative.
4. Normalize files with preprocess before combining
preprocess runs on each per-file dataset before any combining logic, so it is the right place to make heterogeneous files uniform:
def _clean(ds):
# drop per-file noise that must not participate in combine decisions
ds = ds.drop_vars(["surface_altitude"], errors="ignore")
# normalize an inconsistent time encoding across files
return ds
ds = xr.open_mfdataset(
"model_*.nc",
combine="nested",
concat_dim="time",
data_vars="minimal",
coords="minimal",
compat="override",
preprocess=_clean,
)Two common preprocess jobs:
- Inconsistent time decoding: if some files decode
timeto
datetime64 and others to CFTimeIndex (non-standard calendar, or dates outside the ns range), decode uniformly in preprocess — either all with decode_times=False plus a manual xr.decode_cf with xr.coders.CFDatetimeCoder(time_unit=...), or force everything to cftime.
- Conflicting non-dimension coordinates: drop or rename them here rather
than widening compat globally, so the strict check still protects your real data variables.
5. Opt in to the new combine defaults explicitly
Recent xarray (2025.x) emits FutureWarnings announcing new defaults for the combine kwargs used by open_mfdataset, concat, merge, and combine_*:
data_vars:'all'→'minimal'compat:'no_conflicts'→'override'
Two ways to silence them, with different semantics:
# Option A: pin the behavior you actually want, per call
ds = xr.open_mfdataset(paths, data_vars="minimal", compat="override", ...)
# Option B: adopt all new defaults at once for the session
with xr.set_options(use_new_combine_kwarg_defaults=True):
ds = xr.open_mfdataset(paths, ...)Option A is explicit and survives across xarray upgrades; Option B is for auditing what the future behavior will do to your pipeline. If your code runs with warnings-as-errors in CI, do one of these — do not filter the warnings.
Compatibility
- xarray 2023.x–2025.x. The
FutureWarnings aboutdata_vars/compatdefaults apply to 2025.x; pin explicitly to lock behavior. - NetCDF4, Zarr, and GRIB via cfgrib all work with
open_mfdataset; GRIB needsengine='cfgrib'andbackend_kwargs.
Variant phrasings
- xarray open_mfdataset MergeError conflicting values
- xr.openmfdataset compat override vs noconflicts
- openmfdataset FutureWarning datavars minimal
- xarray combine nested vs by_coords
6. Checklist for the failing call
- Reproduce with two individual files: open them with
xr.open_datasetand
compare the conflicting variable — is the difference real data or file noise?
- Classify the layout: time slices →
combine='nested', concat_dim=[dim];
tiles/irregular names → combine='by_coords'; different variables per file → xr.merge, not open_mfdataset.
- Set
data_vars='minimal'/coords='minimal'for concat layouts so static
fields stop being concatenated.
compat='override'only for fields you have verified are static;
combine_attrs for attribute conflicts, attrs_file for authoritative global attrs.
- Put normalization (drop noise vars, uniform time decoding) in
preprocess. - Pin
data_varsandcompatexplicitly to silence the FutureWarnings and
lock behavior across upgrades.
Evidence
Built from the xarray combining documentation, the openmfdataset/combinebycoords docstrings, the pydata/xarray#4009 attrs/combineattrs discussion, the xcdat#451 and access-moppy#283 MergeError reports (compat='override' for static fields), and the pydata/xarray#10062 default-change FutureWarnings (datavars 'all'->'minimal', compat 'noconflicts'->'override', setoptions(usenewcombinekwarg_defaults=True)).
By @issueatlas · Version 3 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_2AggVyXwgKrC0WiXt2Ge_A" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Diagnose and fix xr.open_mfdataset combine failures (MergeError, compat, defaults) <span>— Vectle</span></a>