Skip to content

Fix segfault from opening netCDF files once per variable - #3460

Draft
djhoese wants to merge 4 commits into
pytroll:mainfrom
djhoese:bugfix-netcdf-pervar-open
Draft

Fix segfault from opening netCDF files once per variable#3460
djhoese wants to merge 4 commits into
pytroll:mainfrom
djhoese:bugfix-netcdf-pervar-open

Conversation

@djhoese

@djhoese djhoese commented Sep 9, 2026

Copy link
Copy Markdown
Member

I was getting a seg fault when processing a large METimage pass. It's getting late here so I had Claude put together a commit with a fix in case anyone wanted to take a look. It isn't noted here but it seems tied to vlen strings (which there is only one in the file) that puts HDF5 into a bad state. I plan on filing an xarray issue tomorrow. Below is Claude's commenting.

I HAVE NOT REVIEWED THIS YET

Claude:

NetCDF4FileHandler opened the file with xarray for every variable and closed it again immediately, returning lazy arrays that reopen it at compute time. Every one of those opens builds its own CachingFileManager, and CachingFileManager._make_key() includes a per-manager id, so no two of them ever share an entry in xarray's global FILE_CACHE. Reading more variables than file_cache_maxsize (128 by default) therefore makes that LRU cache evict and close netCDF4 handles while sibling arrays of the same file are still reading through them, which segfaults in libhdf5.

Keep one xarray.Dataset open per group instead, for the lifetime of the file handler, and hand out copies so callers can still modify metadata. Add a close() method to release the datasets before the file handler is deleted, which the METimage base tests need in order to reopen their test file for writing.

Claude-Session: https://claude.ai/code/session_01TKR5WimPBvwWpVgcJ52TNv

  • Closes #xxxx
  • Tests added
  • Fully documented
  • Add your name to AUTHORS.md if not there already

NetCDF4FileHandler opened the file with xarray for every variable and
closed it again immediately, returning lazy arrays that reopen it at
compute time. Every one of those opens builds its own
CachingFileManager, and CachingFileManager._make_key() includes a
per-manager id, so no two of them ever share an entry in xarray's global
FILE_CACHE. Reading more variables than file_cache_maxsize (128 by
default) therefore makes that LRU cache evict and close netCDF4 handles
while sibling arrays of the same file are still reading through them,
which segfaults in libhdf5.

Keep one xarray.Dataset open per group instead, for the lifetime of the
file handler, and hand out copies so callers can still modify metadata.
Add a close() method to release the datasets before the file handler is
deleted, which the METimage base tests need in order to reopen their
test file for writing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TKR5WimPBvwWpVgcJ52TNv
@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.55769% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.36%. Comparing base (07d9bcf) to head (a6abb4f).
⚠️ Report is 28 commits behind head on main.

Files with missing lines Patch % Lines
satpy/readers/fci_l1c_nc.py 94.44% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #3460    +/-   ##
========================================
  Coverage   96.35%   96.36%            
========================================
  Files         465      465            
  Lines       59327    59539   +212     
========================================
+ Hits        57163    57372   +209     
- Misses       2164     2167     +3     
Flag Coverage Δ
behaviourtests 3.56% <0.00%> (-0.02%) ⬇️
unittests 96.44% <98.55%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

djhoese and others added 3 commits September 10, 2026 11:56
With cache_handle=False the variable objects stored in file_content belong
to the handle closed at the end of __init__. Reading them raised
'NetCDF: Not a valid ID' (netCDF4) or 'I/O operation on closed file'
(h5netcdf); for the FCI reader the netCDF4 error was silently swallowed
and produced wrongly padded arrays. Read through xarray instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jjGBN7DkiaVHEnA1qG5dR
Lets a file handler choose how xarray datasets for the groups of a file
are created: one open_dataset per group (default, existing behaviour),
one open_datatree per file, one shared backend store per file with a
child store per group, or a store wrapping the already open
cache_handle=True file handle. The last three keep every group of a
file in a single xarray file-cache slot.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jjGBN7DkiaVHEnA1qG5dR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant