# Diagnose and fix OpenMC cross-section data setup failures
Use this when OpenMC refuses to run (or a material call raises) because it
cannot find nuclear data. Nearly every data error is one of three distinct
problems with different fixes, so read the exact error first and classify it
before downloading anything.
## 1. Read the exact error and classify
OpenMC prints three different messages for three different problems:
- **"ERROR: No cross_sections.xml file was specified in settings.xml or in the
OPENMC_CROSS_SECTIONS environment variable."** — OpenMC cannot find the
`cross_sections.xml` index at all. (In current releases the `<cross_sections>`
element lives in `materials.xml`, not `settings.xml`; the Python API
equivalent is `RuntimeError: No cross_sections.xml file was specified in
materials.xml or in the OPENMC_CROSS_SECTIONS environment variable`.) Fix:
point OpenMC at an existing file (step 2), not download new data.
- **"ERROR: Could not find S(a,b) table X in cross_sections.xml file!"** — the
index was found, but the thermal-scattering table your material requests is
not in it. Fix: the S(alpha,beta) name or the library (step 4), not the
pointer.
- **`ValueError` from `add_element()` / `add_nuclide()`**, e.g. "No data is
available for any of natural isotopes of the element" — the isotope you
asked for exists in your model but not in the data library the index points
to. Fix: the library (step 3), not the pointer.
Do not treat all three as "I need more data" — the first two are usually
configuration, not missing physics.
## 2. Fix the "no cross_sections.xml" pointer
OpenMC resolves the index in this order; set whichever fits your workflow:
1. The `cross_sections` attribute in the Python API, exported as the
`<cross_sections>` element in `materials.xml` (older releases:
`settings.xml`):
```python
materials = openmc.Materials([fuel, water])
materials.cross_sections = '/path/to/nuclear_data/cross_sections.xml'
materials.export_to_xml()
```
2. The `OPENMC_CROSS_SECTIONS` environment variable (recommended for the
shell profile so every run inherits it):
```bash
export OPENMC_CROSS_SECTIONS=/path/to/nuclear_data/cross_sections.xml
```
After setting either, sanity-check that the path exists and that the file
actually references HDF5 data files on disk:
```bash
test -f "$OPENMC_CROSS_SECTIONS" && echo "index found"
head -5 "$OPENMC_CROSS_SECTIONS"
```
A `cross_sections.xml` that lists `.h5` files you never downloaded (or that
live on someone else's machine) produces the same missing-data symptoms as a
bad pointer — the error message won't tell you which, so check the file
contents.
## 3. Get a library that covers your nuclides
If the pointer is fine but nuclides are missing, generate a library whose
contents are derived from your actual materials instead of downloading a
generic bundle and hoping:
```bash
pip install openmc_data_downloader
openmc_data_downloader -l ENDFB-7.1-NNDC -m materials.xml
```
The `-m materials.xml` form downloads exactly the isotopes present in your
materials file and writes a matching `cross_sections.xml`. For common cases:
```bash
openmc_data_downloader -l ENDFB-7.1-NNDC -e Li Si Na -i Fe56 U235 # elements + isotopes
openmc_data_downloader -l FENDL-3.1d -i Li6 # single isotope
openmc_data_downloader -l TENDL-2019 -i stable # all stable isotopes
```
Or do it inside Python — `just_in_time_library_generator()` sets
`OPENMC_CROSS_SECTIONS` for you by default:
```python
import openmc_data_downloader as odd
odd.download_cross_section_data(
mats,
libraries=['ENDFB-7.1-NNDC'],
set_OPENMC_CROSS_SECTIONS=True,
particles=['neutron'],
)
```
Since OpenMC 0.14, depletion runs may include decay-only nuclides with no
neutron data, so a "no data" complaint about a pure decay nuclide is
expected and harmless in depletion — only fissionable/absorbing nuclides in
the transport solve need tables.
## 4. Fix S(alpha,beta) thermal-scattering mismatches
This error means the *name* of the table in your material does not match any
`<library ... type="neutron">` entry with `materials="..."` S(a,b) alias in
your `cross_sections.xml`. Two frequent causes:
- **Legacy table names.** Old example inputs and forum posts use ACE-era
aliases like `lwtr.15t` (water at 550 K) or `lwtr.10t` (293 K). Modern
OpenMC data libraries use names such as `c_H_in_H2O`, `c_Graphite`,
`c_H_in_ZrH`, `c_Be_in_BeO`. Set the current name explicitly:
```python
water.add_s_alpha_beta('c_H_in_H2O')
graphite.add_s_alpha_beta('c_Graphite')
```
- **The table was never downloaded.** The library index you downloaded may
not include S(a,b) tables. Download them by name with the downloader:
```bash
openmc_data_downloader -l ENDFB-7.1-NNDC -e Be O -s c_Be_in_BeO
```
or in Python, declare the table on the material first so `-m
materials.xml` picks it up:
```python
my_mat = openmc.Material()
my_mat.add_element('Be', 0.5)
my_mat.add_element('O', 0.5)
my_mat.add_s_alpha_beta('Be_in_BeO')
```
Note the naming split: the Python API takes names like `Be_in_BeO`, the
`cross_sections.xml` alias is typically `c_Be_in_BeO`; the downloader handles
both forms. If a forum post or old input gives you an alias ending in
`.Nt` / a number like `71c`, that alias belongs to an old data generation
and you should re-derive the current name from your actual library file,
not copy the alias.
## 5. Photon data is a separate download
Neutron-only libraries do not contain photon interaction data. If you enable
photon transport (`settings.photon_transport = True`), request both particle
types when building the library or the run will fail on missing photon
tables:
```bash
openmc_data_downloader -l ENDFB-7.1-NNDC -e Li -p neutron photon
```
```python
odd.download_cross_section_data(
mats,
libraries=['ENDFB-7.1-NNDC'],
set_OPENMC_CROSS_SECTIONS=True,
particles=['neutron', 'photon'],
)
```
## 6. Checklist for the failing command
1. Capture the exact error text and classify it (pointer vs S(a,b) name vs
missing nuclide) — the fix differs for each.
2. Pointer error: set `materials.cross_sections` or `OPENMC_CROSS_SECTIONS`
and verify the file exists with `test -f`.
3. Missing nuclide: regenerate the library from your materials with
`openmc_data_downloader -l [library] -m materials.xml`.
4. S(a,b) error: check the table alias against your `cross_sections.xml`,
update legacy names (e.g. `lwtr.15t`) to current ones (e.g.
`c_H_in_H2O`), and download the table with `-s` if absent.
5. Photon transport: rebuild the library with `particles=['neutron',
'photon']`.
6. Never copy a `cross_sections.xml` path from another machine's forum post
— the HDF5 paths inside it are local to whoever generated it.