---
title: "How to Check Remote Ports Using the nc Command in Linux"
description: "Learn how to check if remote ports are open using the nc (netcat) command in Linux. Covers TCP/UDP testing, port ranges, timeouts, and scripting patterns."
date: 2026-07-12
categories: ["linux"]
tags: ["networking","devops"]
---

Need to know if a port is open on a remote server? The `nc` (netcat) command is the fastest way to find out. One command, instant answer. No browser, no GUI, no heavy tools required.

This guide covers how to check remote ports with `nc` on Linux, including TCP and UDP testing, port ranges, timeouts for scripts, and common gotchas across different netcat implementations.

**Related guides:**

- [Top 100+ Linux Commands You MUST Know](https://www.bitdoze.com/linux-commands/)
- [How to Secure an SSH Server in Linux](https://www.bitdoze.com/secure-ssh-server-linux/)
- [How To Do SSH Port Forwarding in Linux](https://www.bitdoze.com/ssh-tunneling-linux/)
- [How To Monitor Server and Docker Resources](https://www.bitdoze.com/sever-monitoring/)

## What is nc (netcat)?

`nc` is a command-line utility that reads and writes data across network connections using TCP or UDP. People call it the "Swiss army knife" of networking because it can do a lot: port scanning, file transfers, banner grabbing, and acting as a simple client or server.

The original netcat was written by Hobbit in 1995. Since then, several implementations have appeared, and they behave differently:

| Implementation | Default on | Package name | Notes |
|---|---|---|---|
| **netcat-openbsd** | Debian, Ubuntu | `netcat-openbsd` | Supports `-z`, IPv6, proxies |
| **ncat** (from Nmap) | CentOS, RHEL, Fedora | `nmap-ncat` | Supports `-z` (since nmap 7.25), SSL |
| **netcat-traditional** | (legacy) | `netcat-traditional` | Older, fewer features |

Most examples in this guide work with all three, but if something behaves unexpectedly, check which version you're running:

```bash
nc -h 2>&1 | head -1
# or
which nc && ls -l $(which nc)
```

## Install nc on Linux

`nc` might already be installed. If not:

**Debian / Ubuntu:**

```bash
sudo apt install netcat-openbsd
```

Note: On Ubuntu 24.04+, `netcat` is a virtual package. Installing `netcat-openbsd` explicitly is the cleanest approach.

**CentOS / RHEL / Fedora:**

```bash
sudo dnf install nmap-ncat
```

**Arch Linux:**

```bash
sudo pacman -S openbsd-netcat
```

**macOS:**

`nc` comes preinstalled (BSD netcat). It works for basic port checking.

## Check if a single TCP port is open

The basic syntax for checking a remote port:

```bash
nc -zv <host> <port>
```

Flags explained:
- `-z`: scan only, don't send any data after connecting
- `-v`: verbose output (shows success/failure messages)

**Example: check if SMTP is reachable on Gmail:**

```bash
nc -zv smtp.gmail.com 587
```

```
Connection to smtp.gmail.com port 587 [tcp/submission] succeeded!
```

**Example: check a port that's closed:**

```bash
nc -zv smtp.gmail.com 5555
```

```
nc: connectx to smtp.gmail.com port 5555 (tcp) failed: Connection refused
```

**Example: check SSH on your VPS:**

```bash
nc -zv 192.168.1.100 22
```

```
Connection to 192.168.1.100 port 22 [tcp/ssh] succeeded!
```

## Reading the output

`nc` gives you three possible outcomes:

| Output | Meaning |
|---|---|
| `Connection to <host> <port> port [tcp/*] succeeded!` | Port is open, service is listening |
| `Connection refused` | Port is closed or nothing is listening |
| `Operation timed out` | Firewall is dropping packets, or host is unreachable |

"Connection refused" and "timed out" are different problems. Refused means the server actively rejected the connection (port closed). Timed out means you never got a response at all (firewall blocking, wrong IP, or network issue). This distinction matters when troubleshooting.

## Check a range of ports

You can scan multiple ports in one command using a hyphen:

```bash
nc -zv <host> <start>-<end>
```

**Example: scan ports 585 through 590:**

```bash
nc -zv smtp.gmail.com 585-590
```

```
nc: connectx to smtp.gmail.com port 585 (tcp) failed: Connection refused
nc: connectx to smtp.gmail.com port 586 (tcp) failed: Connection refused
Connection to smtp.gmail.com port 587 [tcp/submission] succeeded!
nc: connectx to smtp.gmail.com port 588 (tcp) failed: Connection refused
nc: connectx to smtp.gmail.com port 589 (tcp) failed: Connection refused
nc: connectx to smtp.gmail.com port 590 (tcp) failed: Connection refused
```

**Filter for only open ports:**

```bash
nc -zv smtp.gmail.com 585-590 2>&1 | grep succeeded
```

```
Connection to smtp.gmail.com port 587 [tcp/submission] succeeded!
```

This is useful when scanning a bunch of ports and you only care about the ones that are open.

## Set a connection timeout with -w

By default, `nc` waits a long time before giving up on a connection attempt. For scripts and automation, you almost always want to set a timeout:

```bash
nc -zv -w 3 <host> <port>
```

The `-w 3` flag tells nc to give up after 3 seconds if the connection hasn't been established. Without it, a blocked port can hang for 30+ seconds (the OS TCP timeout).

**Skip DNS resolution with -n:**

If you're passing an IP address, add `-n` to skip DNS lookups. This speeds up scans significantly:

```bash
nc -zvn -w 3 192.168.1.100 22
```

## Check UDP ports

Use the `-u` flag to test UDP ports:

```bash
nc -zuv <host> <port>
```

**Example: check DNS (UDP port 53):**

```bash
nc -zuv 8.8.8.8 53
```

**Important caveat:** UDP is connectionless. Unlike TCP, there's no handshake, so `nc` sends a packet and has no way to confirm it arrived. You might see "succeeded" even if nothing is listening, or you might see no output at all.

For reliable UDP testing, combine `nc` with `tcpdump` on the target machine, or use protocol-specific tools like `dig` for DNS or `iperf3` for throughput.

## Use nc in scripts

A common pattern is waiting for a service to become available before running something else. This comes up in Docker Compose setups, CI/CD pipelines, and deployment scripts:

```bash
#!/bin/bash
HOST=db.example.com
PORT=5432

echo "Waiting for $HOST:$PORT..."
until nc -z -w 2 "$HOST" "$PORT" 2>/dev/null; do
  sleep 1
done
echo "Port $PORT is open. Continuing..."
```

This loop checks the port every second until it's reachable, then proceeds. The `2>/dev/null` suppresses the verbose output so your logs stay clean.

**Check multiple ports in a loop:**

```bash
for port in 80 443 8080; do
  if nc -z -w 2 example.com "$port" 2>/dev/null; then
    echo "Port $port: OPEN"
  else
    echo "Port $port: CLOSED"
  fi
done
```

## Banner grabbing with nc

Beyond port checking, `nc` can grab service banners, the text a server sends when you first connect. This tells you what software and version is running:

```bash
nc -v smtp.gmail.com 25
```

```
220 smtp.gmail.com ESMTP ...
```

Similarly for HTTP:

```bash
printf "HEAD / HTTP/1.1\r\nHost: example.com\r\n\r\n" | nc example.com 80
```

This sends a minimal HTTP request and shows you the raw response headers. Useful for debugging web servers, reverse proxies, or load balancers without curl's overhead.

## Troubleshooting

| Problem | Likely cause | What to try |
|---|---|---|
| `Connection refused` | Port closed, no service listening | Verify service is running on the target (`ss -tlnp` on the target host) |
| `Operation timed out` | Firewall dropping packets, wrong IP | `ping` the host first, check firewall rules (`iptables -L`, `ufw status`) |
| `No route to host` | Network routing issue | Check subnet, gateway, VPN connectivity |
| `nc -z` says "invalid option" | Old ncat version without `-z` support | Update nmap-ncat or use `nc --send-only </dev/null <host> <port>` as a workaround |
| Output is silent | Connection succeeded but no banner | The service doesn't send a greeting. Use `-v` to confirm connection status |
| UDP shows "succeeded" but service isn't responding | UDP is connectionless | Use `tcpdump` or protocol-specific tools to verify |

## nc vs other port-checking tools

`nc` isn't the only way to check ports. Here's how it compares:

| Tool | Best for | Installed by default? | Notes |
|---|---|---|---|
| `nc` | Quick single-port checks, scripts | Often yes | Lightweight, fast, no dependencies |
| `nmap` | Scanning many ports, service detection | No | Overkill for a single port check |
| `curl` | Testing HTTP/HTTPS endpoints | Usually yes | Only works for web protocols |
| `telnet` | Interactive TCP testing | Being phased out | No UDP support, no `-z` equivalent |
| `ss` / `netstat` | Checking local listening ports | Yes | Only works for ports on the machine you're on |

For checking a remote port from the command line, `nc` hits the sweet spot: it's fast, works for both TCP and UDP, and is available on almost every Linux system.

## Conclusion

The `nc` command is the quickest way to check if a remote port is reachable from a Linux terminal. The core command is `nc -zv <host> <port>`. Add `-w` for timeouts in scripts and `-u` for UDP testing.

Just remember: different Linux distros ship different netcat implementations, and they don't all support the same flags. If `nc -zv` behaves strangely, check which version you're running. On modern systems (Ubuntu 22.04+, RHEL 8+, Fedora), the `-z` flag works out of the box with the default netcat package.