diff --git a/ui/build/config.go b/ui/build/config.go
index 1d793ad..0e8db52 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -1835,6 +1835,9 @@ func (c *configImpl) KatiBin() string {
 }
 
 func (c *configImpl) NinjaBin() string {
+	if customNinja, ok := c.environ.Get("CUSTOM_NINJA_BIN"); ok && customNinja != "" {
+		return customNinja
+	}
 	binName := "ninja"
 	if c.UseABFS() {
 		binName = "ninjago"
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index 3837bf3..36f172e 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -1135,3 +1135,41 @@ func TestGetMetricsUploaderApp(t *testing.T) {
 		})
 	}
 }
+
+func TestConfigCustomNinjaBin(t *testing.T) {
+	testCases := []struct {
+		description string
+		env         []string
+		expected    string
+	}{
+		{
+			description: "No CUSTOM_NINJA_BIN env var",
+			env:         []string{},
+			expected:    "prebuilts/build-tools/linux-x86/bin/ninja",
+		},
+		{
+			description: "CUSTOM_NINJA_BIN env var set",
+			env:         []string{"CUSTOM_NINJA_BIN=/usr/bin/ninja"},
+			expected:    "/usr/bin/ninja",
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.description, func(t *testing.T) {
+			env := Environment(tc.env)
+			c := &configImpl{
+				environ: &env,
+			}
+			actual := c.NinjaBin()
+			if tc.expected == "/usr/bin/ninja" {
+				if actual != tc.expected {
+					t.Errorf("expected NinjaBin to be %q, got %q", tc.expected, actual)
+				}
+			} else {
+				if !strings.HasSuffix(actual, "bin/ninja") && !strings.HasSuffix(actual, "bin/ninjago") {
+					t.Errorf("expected NinjaBin to end with bin/ninja or bin/ninjago, got %q", actual)
+				}
+			}
+		})
+	}
+}
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index 2b31024..d977557 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -244,6 +244,7 @@ func runNinja(ctx Context, config Config, ninjaArgs []string) {
 			"BUILD_BROKEN_INCORRECT_PARTITION_IMAGES",
 			// Do not do reanalysis just because we changed ninja commands.
 			"SOONG_NINJA",
+			"CUSTOM_NINJA_BIN",
 			"SOONG_USE_N2",
 			"RUST_BACKTRACE",
 			"RUST_LOG",
diff --git a/ui/build/rbe.go b/ui/build/rbe.go
index 8f99b14..9f7a200 100644
--- a/ui/build/rbe.go
+++ b/ui/build/rbe.go
@@ -119,7 +119,7 @@ func startRBE(ctx Context, config Config) {
 	e := ctx.BeginTrace(metrics.RunSetupTool, "rbe_bootstrap")
 	defer e.End()
 
-	ctx.Status.Status("Starting rbe...")
+	ctx.Status.Status("Starting ninja...")
 
 	cmd := Command(ctx, config, e, "startRBE bootstrap", rbeCommand(ctx, config, bootstrapCmd))
 
@@ -132,7 +132,7 @@ func stopRBE(ctx Context, config Config) {
 	cmd := Command(ctx, config, nil, "stopRBE bootstrap", rbeCommand(ctx, config, bootstrapCmd), "-shutdown")
 	output, err := cmd.CombinedOutput()
 	if err != nil {
-		ctx.Fatalf("rbe bootstrap with shutdown failed with: %v\n%s\n", err, output)
+		ctx.Fatalf("soong bootstrap with shutdown failed with: %v\n%s\n", err, output)
 	}
 
 	if !config.Environment().IsEnvTrue("ANDROID_QUIET_BUILD") && len(output) > 0 {
