diff --git a/src/routing/mod.rs b/src/routing/mod.rs
index 53250a6d..0fffea6d 100644
--- a/src/routing/mod.rs
+++ b/src/routing/mod.rs
@@ -178,6 +178,8 @@ where
     /// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
     /// # };
     /// ```
+    ///
+    /// Also panics if `path` is empty.
     pub fn route<T>(mut self, path: &str, svc: T) -> Self
     where
         T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible>
@@ -186,6 +188,10 @@ where
             + 'static,
         T::Future: Send + 'static,
     {
+        if path.is_empty() {
+            panic!("Invalid route: empty path");
+        }
+
         let id = RouteId::next();
 
         if let Err(err) = self.node.insert(path, id) {
@@ -310,8 +316,10 @@ where
     ///
     /// # Panics
     ///
-    /// Panics if the route overlaps with another route. See [`Router::route`]
+    /// - If the route overlaps with another route. See [`Router::route`]
     /// for more details.
+    /// - If the route contains a wildcard (`*`).
+    /// - If `path` is empty.
     ///
     /// [`OriginalUri`]: crate::extract::OriginalUri
     pub fn nest<T>(mut self, path: &str, svc: T) -> Self
@@ -322,12 +330,16 @@ where
             + 'static,
         T::Future: Send + 'static,
     {
-        let id = RouteId::next();
+        if path.is_empty() {
+            panic!("Invalid route: empty path");
+        }
 
         if path.contains('*') {
             panic!("Invalid route: nested routes cannot contain wildcards (*)");
         }
 
+        let id = RouteId::next();
+
         let path = if path == "/" {
             format!("/*{}", NEST_TAIL_PARAM)
         } else {
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index da6c5a64..c351cd79 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -658,6 +658,20 @@ async fn static_and_dynamic_paths() {
     assert_eq!(res.text().await, "static");
 }
 
+#[tokio::test]
+#[should_panic(expected = "Invalid route: empty path")]
+async fn empty_route() {
+    let app = Router::new().route("", get(|| async {}));
+    TestClient::new(app);
+}
+
+#[tokio::test]
+#[should_panic(expected = "Invalid route: empty path")]
+async fn empty_route_nested() {
+    let app = Router::new().nest("", get(|| async {}));
+    TestClient::new(app);
+}
+
 pub(crate) fn assert_send<T: Send>() {}
 pub(crate) fn assert_sync<T: Sync>() {}
 pub(crate) fn assert_unpin<T: Unpin>() {}