diff --git a/src/libstore/build/substitution-goal.cc b/src/libstore/build/substitution-goal.cc index d16e530a4..ac18de304 100644 --- a/src/libstore/build/substitution-goal.cc +++ b/src/libstore/build/substitution-goal.cc @@ -268,16 +268,18 @@ Goal::Co PathSubstitutionGoal::tryToRun( try { promise.get_future().get(); } catch (std::exception & e) { - printError(e.what()); - /* Cause the parent build to fail unless --fallback is given, or the substitute has disappeared. The latter case behaves the same as the substitute never having existed in the first place. */ try { throw; - } catch (SubstituteGone &) { + } catch (SubstituteGone & sg) { + /* Missing NARs are expected when they've been garbage collected. + This is not a failure, so log as a warning instead of an error. */ + logWarning({.msg = sg.info().msg}); } catch (...) { + printError(e.what()); substituterFailed = true; } diff --git a/tests/functional/binary-cache.sh b/tests/functional/binary-cache.sh index 2c102df07..d801ac6aa 100755 --- a/tests/functional/binary-cache.sh +++ b/tests/functional/binary-cache.sh @@ -111,7 +111,13 @@ clearStore mv "$cacheDir/nar" "$cacheDir/nar2" -nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" +nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" 2>&1 | tee "$TEST_ROOT/log" + +# Verify that missing NARs produce warnings, not errors +# The build should succeed despite the warnings +grepQuiet "does not exist in binary cache" "$TEST_ROOT/log" +# Ensure the message is not at error level by checking that the command succeeded +[ -e "$TEST_ROOT/result" ] mv "$cacheDir/nar2" "$cacheDir/nar"