Diagnosing Spack Concretization Failures Before They Block Your Build
When Spack reports unsatisfiable constraints, the problem usually lies in compiler detection, configuration pins, or virtual provider selection—not in the source code. This guide maps common symptoms to targeted checks and fixes.
13 Aug 2025, 13:55 UTC

Recognizable Condition
A Spack build stops before compilation when the concretizer cannot map your request to a concrete dependency graph. The solver prints Concretization failed, no feasible solution, or unsatisfiable constraints, and no source code is downloaded. These messages are not compiler errors; they mean the requested versions, variants, compilers, and virtual providers cannot coexist under your current configuration.
Cause and Diagnostic Mapping
| Error Pattern | Likely Cause | Diagnostic Signal |
|---|---|---|
| No compiler matches target | Missing or stale compiler entry | spack compiler list omits the expected compiler or target os/arch |
| External library conflict | packages.yaml marks a system package external without required variants | spack external find lists entries; the spec fails only when externals are enabled |
| Missing virtual provider | No package provides mpi, blas, lapack, or another virtual | spack info <pkg> shows a virtual dependency but no provider is installed |
| Version range too tight | User spec pins a version outside recipe bounds | spack info <pkg> declares versions narrower than the request |
| Variant contradiction | Requested +shared conflicts with ~shared or a default | Solver error names the conflicting variant; spack info <pkg> lists variant defaults |
Ordered Checks
Rule out a stale cache. Run
spack spec --fresh <spec>in your shell. Run it twice; identical output confirms the failure is deterministic.Inspect compilers. Run
spack compiler list. Confirm that a compiler matching your target operating system and architecture appears.Review configuration. Check
packages.yamlandcompilers.yamlfor restrictiverequire:blocks orexternals:entries. You can inspect them withspack config get packagesandspack config get compilers.Read solver reasoning. Depending on your Spack version, run
spack spec -I <spec>orspack solve --show-errors <spec>. The output identifies which constraint the solver could not satisfy.Check the recipe. Run
spack info <pkg>. Compare the versions and variants you requested against the declared dependencies and variant defaults.
Targeted Fixes
Each fix corresponds to a finding from the checks above.
Compiler detection
If spack compiler list is missing an expected compiler, run spack compiler find. This scans your PATH and adds detected compilers to compilers.yaml. Run it as your normal user; no elevated permissions are required. Risk: it may detect compilers you do not intend to use. After running it, confirm the new entry with spack compiler list.
External package conflicts
If a system library is marked external but lacks a required variant, remove its externals: block from packages.yaml. Alternatively, run spack external find --not-buildable to limit detection to packages that cannot be built from source. Before editing, back up packages.yaml; a YAML syntax error will break every Spack command until fixed. Verify the change by running spack -C /dev/null spec <spec> to test without user configuration.
Missing virtual providers
If a package depends on a virtual such as mpi but no provider is installed, install one explicitly, for example spack install openmpi. You can also add a providers.yaml entry to prefer a specific implementation. Check that the virtual is now satisfied by re-running spack spec <spec>.
Over-constrained versions
If the recipe caps a dependency below your requested version, relax the spec. For example, a request like spack spec myapp ^python@3.11 fails when myapp declares depends_on('python@:3.9'). Change the pin to ^python@3.9 or remove it entirely and let the solver choose. Use spack info myapp to confirm the relaxed version falls within the declared range.
Conflicting variants
If the solver reports a variant contradiction, adjust the user spec or override the default in packages.yaml. For instance, if a package defaults to ~shared but your request forces +shared on a dependency that forbids it, drop the explicit variant from the spec. Verify with spack spec <spec>.
Environment-Specific Failures
Command-line specs can succeed while spack env concretization fails. Environments unify views and enforce matrix constraints defined in spack.yaml. Before assuming a package bug, run spack env status and inspect the spack.yaml file, including any concretizer: settings. A constraint that is satisfiable in isolation may become unsatisfiable when unified with other roots in the same environment.
Escalation Criteria
Escalate to the Spack maintainers only after you have eliminated local causes. File an issue when all of the following are true:
- A minimal spec fails after clearing caches with
spack clean -m. - The failure reproduces with user configuration disabled:
spack -C /dev/null spec <spec>. - The failure occurs on a recent Spack release.
Include the full error output from spack spec --show-errors <spec>, the relevant packages.yaml and compilers.yaml contents, and the version string from spack --version.
Verification and Limitations
To verify a fix, run spack spec --fresh <spec> twice and confirm identical, successful output. To isolate configuration, compare the result with spack -C /dev/null spec <spec>. If the latter succeeds, the problem is in your local YAML files.
Spack has transitioned from the original concretizer to the clingo-based solver. Error wording and available flags differ between them. Verify the active concretizer with spack config get concretizer and consult documentation matching your version. Additionally, spack external find can mark system libraries as external even when they lack required variants, creating hidden unsatisfiable constraints that disappear only when the external entry is removed.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.