Essential Network Debugging with Netcat
Using the Swiss Army Knife of network tools
For engineers and system administrators, quickly verifying network connectivity—especially to specific ports on remote hosts—is a fundamental task. While comprehensive tools like telnet and nmap exist, the versatile netcat (usually aliased as nc) offers a fast, simple, and often pre-installed utility for this job.
Netcat is installed on most Linux distributions by default. It’s also found on macOS, can be installed on BSDs if missing, and some network devices make it available in a guest shell or it may be available for installation in those guest shells. I have run across it in the wild on a Juniper Layer 3 switch.
This article covers how to use netcat to check port connectivity and how to leverage its functionality for basic port scanning.
Verifying Connectivity to a Specific Port
The most common use of netcat is establishing a TCP connection to a server to see if a specific service is running and accessible.
The Basic Command
To check if a host is reachable on a given port, you use the following syntax.
$ nc -v \ <host> <port>
nc: The command to invoke netcat.-v: The verbose option. This is crucial as it instructsnetcatto print out information about the connection, including success or failure messages, which is the key to verifying connectivity.<host>: The target hostname or IP address (e.g.,google.comor192.168.1.1).<port>: The target port number (e.g.,80for HTTP,22for SSH,443for HTTPS).
💡 Example: Checking Port 22 (SSH)
If you’re troubleshooting an SSH connection to a server at 192.168.1.5, you’d run:
$ nc -v 192.168.1.5 22
Successful Output:
A successful connection will show the connection details and then typically hang, waiting for input. You’ll see output similar to this:
Connection to 192.168.1.5 22 port [tcp/*] succeeded! SSH-2.0-OpenSSH_9.2p1 Debian-2 ...
Press CTRL-C to terminate the connection.
Failed Output (Port Closed or Filtered):
If the port is closed or blocked by a firewall, the output will indicate the failure almost immediately:
nc: connect to 192.168.1.5 port 22 (tcp) failed: Connection refused
Failed Output (Host Unreachable or Filtered):
If the host is unreachable or a firewall is silently dropping packets (not sending a refused response), the command will eventually time out after a delay (which can be explicitly set with the -w option):
nc: connect to 192.168.1.5 port 22 (tcp) failed: Operation timed out
Simple Port Scanning with Netcat
While netcat isn’t a dedicated port scanner, it can be quickly used to check a range of ports to find open services. This is especially useful for a quick check when a dedicated tool like nmap isn’t available or required.
Using the Range Syntax
Netcat allows you to specify a port range instead of a single port. When combined with the -z option (zero-I/O), it performs a simple connect-and-close check without attempting to send data or wait for a banner, making it ideal for scanning.
$ nc -vz <host> <start_port>-<end_port>
-z: The zero-I/O mode. This tellsnetcatto just report the status of the connection without sending any data. It’s essentially a “scanning” mode.
Example: Scanning Common Ports
To quickly check a host for open common web and service ports (80, 443, 22, 23):
$ nc -zv 192.168.1.5 20-445
Note that this scans all the TCP ports in the range 20 through 445, which encompasses the common ports.
The output will clearly list every port attempt, thanks to the verbose (-v) option, only showing “succeeded!” for the open ports.
Example Output:
nc: connect to 192.168.1.5 port 20 (tcp) failed: Connection refused
nc: connect to 192.168.1.5 port 21 (tcp) failed: Connection refused
Connection to 192.168.1.5 22 port [tcp/*] succeeded!
nc: connect to 192.168.1.5 port 23 (tcp) failed: Connection refused... (many more lines)
Connection to 192.168.1.5 80 port [tcp/*] succeeded!
...
Connection to 192.168.1.5 443 port [tcp/*] succeeded!
By filtering this output using grep, you can extract a clean list of open ports:
$ nc -zv 192.168.1.5 20-445 2>&1 | grep ‘succeeded’
(The 2>&1 redirects the verbose output, which is sent to standard error, to standard output so grep can process it.)
Filtered Output:
Connection to 192.168.1.5 22 port [tcp/*] succeeded!
Connection to 192.168.1.5 80 port [tcp/*] succeeded!
Connection to 192.168.1.5 443 port [tcp/*] succeeded!
Note on UDP Scanning
Netcat can also check UDP ports using the -u option:
$ nc -vzu <host> <port>
However, scanning for open UDP ports is less reliable. Since UDP is connectionless, a closed port typically results in a port unreachable message. If the port is open or a firewall is blocking it, you may simply receive no response, making it difficult to differentiate between a filtered port and a successful check. For UDP, netcat is generally best used for actual data transmission testing.
This article covered how to use netcat for checking connectivity between hosts and ports across a network. This is useful because not only can you use it to confirm that path between hosts is open, but you can also see if something is preventing connections on specific ports. When troubleshooting it can point you to access control lists or firewalls that are interfering with network communications.
Netcat has other uses, but we’ll save them for future articles.



Solid walkthrough on a tool that often gets overlooked. The zero-I/O mode for scanning is pragmatic, especially when nmap isn't availabel or overkill for a quick connectivity check. One thing I've found helpful when troubleshooting intermittent issues is combining nc with watch to poll ports repeatedly and catch transient failures that aone-off check would miss.