diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index e38a574ca2310..7a684c89fe31f 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1171,7 +1171,6 @@ def bootstrap(help_triggered):
     env = os.environ.copy()
     env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
     env["BOOTSTRAP_PYTHON"] = sys.executable
-    env["RUSTC_BOOTSTRAP"] = '1'
     if build.rustc_commit is not None:
         env["BOOTSTRAP_DOWNLOAD_RUSTC"] = '1'
     run(args, env=env, verbose=build.verbose, is_bootstrap=True)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 2224bf5f66e90..68d0d685ebb40 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1201,6 +1201,14 @@ impl<'a> Builder<'a> {
         // this), as well as #63012 which is the tracking issue for this
         // feature on the rustc side.
         cargo.arg("-Zbinary-dep-depinfo");
+        match mode {
+            Mode::ToolBootstrap => {
+                // Restrict the allowed features to those passed by rustbuild, so we don't depend on nightly accidentally.
+                // HACK: because anyhow does feature detection in build.rs, we need to allow the backtrace feature too.
+                rustflags.arg("-Zallow-features=binary-dep-depinfo,backtrace");
+            }
+            Mode::Std | Mode::Rustc | Mode::ToolStd | Mode::Codegen | Mode::ToolRustc => {}
+        }
 
         cargo.arg("-j").arg(self.jobs().to_string());
         // Remove make-related flags to ensure Cargo can correctly set things up
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index fcef784d2d1fa..be6655ddb61d0 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -881,6 +881,10 @@ impl Step for RustcBook {
         if self.validate {
             cmd.arg("--validate");
         }
+        if !builder.unstable_features() {
+            // We need to validate nightly features, even on the stable channel.
+            cmd.env("RUSTC_BOOTSTRAP", "1");
+        }
         // If the lib directories are in an unusual location (changed in
         // config.toml), then this needs to explicitly update the dylib search
         // path.