diff --git a/README.md b/README.md
index 3f8b8597..694345d4 100644
--- a/README.md
+++ b/README.md
@@ -92,7 +92,6 @@ in **[`TOOLS.md`](./TOOLS.md)** but a brief description of each tool is included
  - **`energy_scan`**: Performs a continuous energy scan to check for non-Zigbee interference.
  - **`flash_read`**: For CC2531s, reads firmware from flash.
  - **`flash_write`**: For CC2531s, writes a firmware `.bin` to flash.
- - **`form_network`**: Forms a network with randomized settings on channel 15.
  - **`network_backup`**: Backs up the network data and device information into a human-readable JSON document.
  - **`network_restore`**: Restores a JSON network backup to the adapter.
  - **`network_scan`**: Actively sends beacon requests for network stumbling.
diff --git a/TOOLS.md b/TOOLS.md
index c699cf27..0de0da1f 100644
--- a/TOOLS.md
+++ b/TOOLS.md
@@ -189,16 +189,6 @@ $ python -m zigpy_znp.tools.nvram_reset /dev/serial/by-id/your-radio
 
 Some warnings are normal, as not all entries will be present in every device.
 
-## Network formation
-Form a new network on the command line:
-
-```console
-$ python -m zigpy_znp.tools.form_network /dev/serial/by-id/your-radio
-```
-
-Currently no command line options are supported so the network will be formed only on
-channel 15 with randomly-generated settings.
-
 ## Network scan
 Nearby routers can be discovered by performing an active network scan. Pass `-a` to
 prevent beacon deduplication and pass `-c 11,15` to narrow the set of channels scanned.
diff --git a/tests/application/test_startup.py b/tests/application/test_startup.py
index 2c6147dc..4973e6ed 100644
--- a/tests/application/test_startup.py
+++ b/tests/application/test_startup.py
@@ -203,18 +203,6 @@ async def test_led_mode(device, led_mode, make_application):
     await app.shutdown()
 
 
-@pytest.mark.parametrize("device", FORMED_DEVICES)
-async def test_auto_form_unnecessary(device, make_application, mocker):
-    app, znp_server = await make_application(server_cls=device)
-    mocker.patch.object(app, "form_network", new=CoroutineMock())
-
-    await app.startup(auto_form=True)
-
-    assert app.form_network.call_count == 0
-
-    await app.shutdown()
-
-
 @pytest.mark.parametrize("device", EMPTY_DEVICES)
 async def test_auto_form_necessary(device, make_application, mocker):
     app, znp_server = await make_application(server_cls=device)
diff --git a/tests/tools/test_form_network.py b/tests/tools/test_form_network.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/zigpy_znp/tools/energy_scan.py b/zigpy_znp/tools/energy_scan.py
index 3eb0fb85..8d3939ea 100644
--- a/zigpy_znp/tools/energy_scan.py
+++ b/zigpy_znp/tools/energy_scan.py
@@ -25,7 +25,6 @@ async def perform_energy_scan(radio_path, num_scans=None):
         await app.start_network(read_only=True)
     except NetworkNotFormed as e:
         LOGGER.error("Could not start application: %s", e)
-        LOGGER.error("Form a network with `python -m zigpy_znp.tools.form_network`")
         return
 
     LOGGER.info("Running scan...")