diff --git a/Cargo.lock b/Cargo.lock
index 91a03d4f6..1a1a30742 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2641,6 +2641,7 @@ dependencies = [
"watchexec-filterer-globset",
"watchexec-signals",
"watchexec-supervisor",
+ "which",
"zip",
]
diff --git a/Cargo.toml b/Cargo.toml
index f63747a40..1162c566c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -93,6 +93,7 @@ watchexec = "^3.0"
watchexec-filterer-globset = "3.0"
watchexec-signals = "2.0"
watchexec-supervisor = "1.0"
+which = "^4.4"
zip = { version = "^0.6", default-features = false, features = ["deflate"] }
time = "0.3.36"
diff --git a/docs/src/ref/v2cli.md b/docs/src/ref/v2cli.md
index 4d18d794e..dac245e0d 100644
--- a/docs/src/ref/v2cli.md
+++ b/docs/src/ref/v2cli.md
@@ -45,8 +45,13 @@ or symlink the `tectonic` binary to `nextonic` manually.
The V2 interface also supports external commands. If you run `tectonic -X cmd`, where `cmd` is NOT built into Tectonic, Tectonic will search for a binary called `tectonic-cmd` and run it if it exists.
+In particular, if a `tectonic-biber` binary is found it will be preferred over
+the regular `biber` binary when generating bibliography with the `biblatex`
+package. This may help resolve [possible version mismatch][biber-mismatch]
+between `biber` and the bundled `biblatex` files when there are multiple TeX
+installations on a system.
-
+[biber-mismatch]: https://github.com/tectonic-typesetting/tectonic/issues/893
## Migration plan
diff --git a/src/driver.rs b/src/driver.rs
index 320ef64fb..ba61d2dfe 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -37,6 +37,7 @@ use tectonic_io_base::{
stdstreams::{BufferedPrimaryIo, GenuineStdoutIo},
InputHandle, IoProvider, OpenResult, OutputHandle,
};
+use which::which;
use crate::{
ctry, errmsg,
@@ -1682,7 +1683,7 @@ impl ProcessingSession {
Some(RerunReason::Bibtex)
} else {
warnings = self.tex_pass(None, status)?;
- let maybe_biber = self.check_biber_requirement()?;
+ let maybe_biber = self.check_biber_requirement(status)?;
if let Some(biber) = maybe_biber {
self.bs.external_tool_pass(&biber, status)?;
@@ -2033,7 +2034,10 @@ impl ProcessingSession {
/// `loqreq` package to figure out what files `biber` needs. This
/// functionality should probably become more generic, but I don't have a
/// great sense as to how widely-used `logreq` is.
- fn check_biber_requirement(&self) -> Result