diff --git a/safesocket/safesocket_darwin.go b/safesocket/safesocket_darwin.go
index 1e15102c0..0a863b496 100644
--- a/safesocket/safesocket_darwin.go
+++ b/safesocket/safesocket_darwin.go
@@ -15,6 +15,7 @@ import (
 	"path/filepath"
 	"strconv"
 	"strings"
+	"sync"
 )
 
 func init() {
@@ -49,6 +50,8 @@ func localTCPPortAndTokenMacsys() (port int, token string, err error) {
 	return port, auth, nil
 }
 
+var warnAboutRootOnce sync.Once
+
 func localTCPPortAndTokenDarwin() (port int, token string, err error) {
 	// There are two ways this binary can be run: as the Mac App Store sandboxed binary,
 	// or a normal binary that somebody built or download and are being run from outside
@@ -83,6 +86,14 @@ func localTCPPortAndTokenDarwin() (port int, token string, err error) {
 				}
 			}
 		}
+		if os.Geteuid() == 0 {
+			// Log a warning as the clue to the user, in case the error
+			// message is swallowed. Only do this once since we may retry
+			// multiple times to connect, and don't want to spam.
+			warnAboutRootOnce.Do(func() {
+				fmt.Fprintf(os.Stderr, "Warning: The CLI is running as root from within a sandboxed binary. It cannot reach the local tailscaled, please try again as a regular user.\n")
+			})
+		}
 		return 0, "", fmt.Errorf("failed to find sandboxed sameuserproof-* file in TS_MACOS_CLI_SHARED_DIR %q", dir)
 	}