Connectivity Testing

Quote

“Everything fails, all the time.”

Werner Vogels, AWS re:Invent keynote (2012)

The first question in any network debugging session is: “Can my client reach the server at all?” This seems simple, but there are multiple layers that can fail: DNS resolution, TCP routing, firewall rules, and the service itself. Working through the layers systematically turns a 2-hour debugging session into a 5-minute one.


flowchart TD
    A([Start: can I reach the server?]) --> B[Step 1: DNS<br>dig +short hostname]
    B --> B1{Resolves?}
    B1 -- No --> B2[Check /etc/resolv.conf<br>VPC DNS settings]
    B1 -- Yes --> C[Step 2: ICMP<br>ping -c 3 IP]
    C --> C1{Responds?}
    C1 -- Timeout --> C2[Possibly blocked by firewall<br>Skip to Step 3 on GCP]
    C1 -- Yes --> D[Step 3: TCP port<br>nc -zv -w 5 IP port]
    C2 --> D
    D --> D1{Port state?}
    D1 -- Refused --> D2[Host alive, service not running<br>or wrong port]
    D1 -- Timed out --> D3[Firewall blocking port<br>or wrong IP]
    D1 -- Succeeded --> E[Step 4: App auth<br>sqlcmd / psql / redis-cli]
    E --> E1{Auth OK?}
    E1 -- Login failed --> E2[Wrong credentials<br>or insufficient privileges]
    E1 -- Cannot open DB --> E3[Database does not exist]
    E1 -- Timeout --> E4[Connection pool exhausted<br>or server overloaded]
    E1 -- Connected --> F([Connectivity confirmed])

Linux connectivity testing tools

This section covers the core Linux tools for diagnosing network connectivity at each layer: nc and /dev/tcp for TCP port reachability, dig for DNS resolution, traceroute and mtr for path tracing, and ss for inspecting local listening ports.

Linux | nc | port reachability and sweeping

nc (netcat) is the primary tool for testing whether a TCP port is open on a remote host. It can also sweep multiple ports in a loop, making it useful as a first diagnostic step after firewall changes or when connecting to a new VM.

Test whether a single port is open

-z runs nc in scan mode — it opens and immediately closes the connection without sending any data, which is the correct way to probe port availability. -v enables verbose output so the result is printed to stderr. -w 5 sets a 5-second timeout to avoid hanging on unreachable hosts.

nc -zv -w 5 hostname 1433
Connection to hostname (10.132.0.2) 1433 port [tcp/ms-sql-s] succeeded!

Refused vs timed out diagnosis

  • Refused = the host is reachable but nothing is listening on that port (service down, wrong port number).
  • Timed out = packets are being dropped (firewall rule, host unreachable, wrong IP).

“Refused” is good news — the host is alive. “Timed out” means a network-layer problem.

Test a port without netcat installed

Bash exposes a built-in TCP pseudo-device at /dev/tcp/<host>/<port>. Opening this path attempts a TCP connection — no external tools required. This works on minimal containers and Docker images where netcat is not installed. timeout 5 prevents the shell from hanging if the host is unreachable.

timeout 5 bash -c "echo > /dev/tcp/hostname/1433" && echo "OPEN" || echo "CLOSED"
OPEN

Sweep multiple ports in a single pass

When connecting to a new environment or diagnosing after firewall changes, sweeping all relevant data engineering ports at once is faster than testing them individually. The loop below checks the most common ports and filters the verbose output to only show the result line.

for port in 1433 5432 6379 8080; do
    nc -zv -w 3 hostname $port 2>&1 | grep -E "succeeded|refused|timed out"
done
Connection to hostname 1433 port [tcp/ms-sql-s] succeeded!
Connection to hostname 5432 port [tcp/postgresql] succeeded!
nc: connect to hostname port 6379 (tcp) timed out: Operation now in progress
Connection to hostname 8080 port [tcp/http-alt] refused
FlagSyntaxDescription
-znc -z host portScan mode — connect and close immediately without sending data
-vnc -v host portVerbose — print result to stderr
-w <n>nc -w 5 host portTimeout after n seconds; prevents hanging on unreachable hosts
-unc -u host portUse UDP instead of TCP
-lnc -l -p portListen mode — start a server on the given port
-pnc -p 4444 host portSpecify the local source port
-nnc -n host portNumeric only — skip DNS resolution
-knc -k -l -p portKeep listening after the first connection closes (multi-client)

Linux | dig | DNS resolution

dig (Domain Information Groper) is the standard tool for querying DNS records. It supports all record types (A, AAAA, CNAME, MX, TXT, NS, SOA) and lets you target specific resolvers.

Look up the IP address of a hostname

+short strips all metadata from the output and returns only the answer section — the resolved IP address or CNAME target.

dig +short hostname
10.132.0.2

Query a specific record type

Appending a record type (A, AAAA, MX, TXT, NS, CNAME) constrains the query to that type. This avoids ambiguity when +short returns a CNAME instead of an IP.

dig hostname A
 
; <<>> DiG 9.18.12 <<>> hostname A
;; ANSWER SECTION:
hostname.       300  IN  A  10.132.0.2

Query a specific DNS server

@8.8.8.8 overrides the system resolver and queries Google’s public DNS directly. Use this when you suspect the local resolver has stale cache entries or is misconfigured.

dig @8.8.8.8 hostname
 
; <<>> DiG 9.18.12 <<>> @8.8.8.8 hostname
; (1 server found)
;; ANSWER SECTION:
hostname.       299  IN  A  203.0.113.10

dig +short may return a CNAME, not an IP

If the hostname is an alias, dig +short hostname returns the CNAME target rather than the final IP address. The returned CNAME must itself be resolved in a second query.

Force A-record resolution directly

Use dig +short hostname A to force resolution to the A record, skipping intermediate CNAME output. This returns the IP even if the hostname is a CNAME alias.

FlagSyntaxDescription
+shortdig +short hostnameReturn only the answer — no metadata
+noall +answerdig +noall +answer hostnameShow only the answer section with full TTL and record data
@<server>dig @8.8.8.8 hostnameQuery a specific DNS server instead of the system resolver
-xdig -x 10.132.0.2Reverse DNS lookup (IP to hostname)
+tracedig +trace hostnameTrace the full delegation path from root servers
+dnssecdig +dnssec hostnameRequest DNSSEC signatures in the response
+tcpdig +tcp hostnameForce query over TCP instead of UDP

Linux | traceroute | network path tracing

traceroute shows each hop between the local machine and the destination, reporting the round-trip time for each router. If the trace stops at a specific hop, that is where a firewall or routing failure is occurring. Hops displaying *** are blocking ICMP or dropping probe packets.

Trace the path to a host using TCP

-T switches traceroute from its default UDP probes to TCP SYN packets. TCP probes are more likely to pass through firewalls than UDP or ICMP, especially on GCP where ICMP is blocked between VPCs by default.

traceroute -T hostname
traceroute to hostname (10.132.0.2), 30 hops max, 60 byte packets
 1  10.142.0.1  0.421 ms  0.398 ms  0.387 ms
 2  172.16.0.1  1.234 ms  1.218 ms  1.201 ms
 3  10.132.0.2  2.105 ms  2.089 ms  2.074 ms

traceroute uses UDP probes by default

The default UDP mode is frequently blocked by corporate firewalls and GCP VPC rules. Hops that show *** may actually be reachable — they are just silently dropping UDP probes.

Use TCP mode for reliable results on GCP

Run traceroute -T hostname to send TCP SYN packets. These follow the same path as real application traffic and are not filtered by GCP’s default ICMP rules.

FlagSyntaxDescription
-Ttraceroute -T hostUse TCP SYN packets instead of UDP datagrams
-Itraceroute -I hostUse ICMP ECHO probes instead of UDP
-p <port>traceroute -T -p 1433 hostSpecify destination port (TCP/UDP mode)
-m <n>traceroute -m 20 hostSet the maximum TTL / number of hops (default 30)
-ntraceroute -n hostDo not resolve hostnames — show IP addresses only
-w <n>traceroute -w 2 hostWait n seconds for a response per probe
-q <n>traceroute -q 1 hostSend n probes per hop (default 3); use 1 for faster output

Linux | mtr | real-time path analysis

mtr combines ping and traceroute into a continuously updating display. It probes each hop repeatedly and accumulates statistics on loss percentage, average latency, and jitter. A sudden latency spike at a specific hop indicates a bottleneck at that router. Packet loss at a hop indicates congestion or active packet drops. Install with apt install mtr.

Run a fixed-count path analysis

-c 10 sends 10 probes per hop and then exits. Without -c, mtr runs interactively until interrupted. Use -c in scripts or when you need a one-shot report.

mtr -c 10 hostname
Start: 2026-04-03T10:00:00+0000
HOST: client                    Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.142.0.1               0.0%    10    0.4   0.4   0.3   0.5   0.1
  2.|-- 172.16.0.1               0.0%    10    1.2   1.3   1.1   1.5   0.1
  3.|-- 10.132.0.2               0.0%    10    2.1   2.1   2.0   2.3   0.1

Generate a report without interactive mode

-r (report mode) combined with -c runs mtr non-interactively and prints the summary table to stdout. Use this in shell scripts or when piping output elsewhere.

mtr -r -c 10 hostname
Start: 2026-04-03T10:00:00+0000
HOST: client                    Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.142.0.1               0.0%    10    0.4   0.4   0.3   0.5   0.1
  2.|-- 172.16.0.1               0.0%    10    1.2   1.3   1.1   1.5   0.1
  3.|-- 10.132.0.2               0.0%    10    2.1   2.1   2.0   2.3   0.1
FlagSyntaxDescription
-c <n>mtr -c 10 hostSend n probes per hop, then exit
-rmtr -r -c 10 hostReport mode — non-interactive, prints summary to stdout
-nmtr -n hostDo not resolve hostnames — show IPs only
-Tmtr -T hostUse TCP SYN probes instead of ICMP
-P <port>mtr -T -P 1433 hostDestination port for TCP/UDP probes
-bmtr -b hostShow both hostnames and IP addresses
-i <n>mtr -i 0.5 hostProbe interval in seconds (default 1)
-umtr -u hostUse UDP datagrams instead of ICMP

Linux | ss | local listening ports

ss is the modern replacement for netstat. It reads socket state directly from the kernel and is significantly faster than netstat on hosts with many connections. Use it to verify that a service is actually bound to the expected port before attempting remote connectivity tests.

List all listening TCP sockets with process names

-t filters to TCP sockets, -l to listening state only, -n disables hostname/port resolution (shows raw IPs and port numbers), and -p shows the owning process name and PID. For deeper connection state analysis, see socket-inspection.

ss -tlnp
State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN  0       128     0.0.0.0:1433        0.0.0.0:*          users:(("sqlservr",pid=1234,fd=3))
LISTEN  0       128     0.0.0.0:5432        0.0.0.0:*          users:(("postgres",pid=5678,fd=5))
LISTEN  0       4096    127.0.0.1:6379      0.0.0.0:*          users:(("redis-server",pid=9012,fd=6))

Filter to a specific port

Appending sport = :<port> limits output to sockets bound to that port. This is faster than piping through grep on hosts with hundreds of connections.

ss -tlnp sport = :1433
State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN  0       128     0.0.0.0:1433        0.0.0.0:*          users:(("sqlservr",pid=1234,fd=3))
FlagSyntaxDescription
-tss -tShow TCP sockets only
-uss -uShow UDP sockets only
-lss -lShow only listening sockets
-nss -nDo not resolve hostnames or port names
-pss -pShow process name and PID for each socket
-ass -aShow all sockets (listening and established)
-sss -sPrint a summary of socket counts by state
sport = :<n>ss -tlnp sport = :1433Filter by local port number
dport = :<n>ss -tnp dport = :443Filter by remote (destination) port number

Linux | systematic debugging walkthrough

Connectivity failures rarely announce their cause. The most efficient approach is to work up the network stack layer by layer, confirming each one before moving to the next. Each step below narrows the problem space.

Step 1 — resolve the hostname

DNS failure produces an empty result. An empty response means /etc/resolv.conf is misconfigured, the VPC DNS settings are wrong, or the hostname has no record in the relevant zone.

dig +short data-pipeline-sql
10.132.0.2

Step 2 — confirm ICMP reachability

ping verifies basic IP routing. On GCP, ICMP is blocked by default — a timeout here does not confirm the host is down. Always proceed to Step 3 regardless.

ping -c 3 10.132.0.2
PING 10.132.0.2 (10.132.0.2) 56(84) bytes of data.
64 bytes from 10.132.0.2: icmp_seq=1 ttl=64 time=0.421 ms
64 bytes from 10.132.0.2: icmp_seq=2 ttl=64 time=0.398 ms
64 bytes from 10.132.0.2: icmp_seq=3 ttl=64 time=0.387 ms
--- 10.132.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss

ping uses ICMP, which GCP blocks by default

A ping timeout does not mean the host is unreachable. GCP’s default firewall rules block ICMP between VPCs. A timeout at this step is inconclusive.

Skip to TCP port test on GCP

Go directly to Step 3 (nc -zv) when working in GCP environments. TCP port tests use the same path as real application traffic and are not blocked by the default ICMP deny rule.

Step 3 — test the TCP port

A refused response means the host is alive but the service is not listening on that port. A timeout means a firewall rule is dropping packets between client and server.

nc -zv -w 5 10.132.0.2 1433
Connection to 10.132.0.2 1433 port [tcp/ms-sql-s] succeeded!

Step 4 — authenticate at the application layer

If the TCP connection succeeds but the application rejects the connection, the problem is in credentials, database existence, or server capacity. -l 10 sets a 10-second login timeout. See sql-server-authentication for login types and troubleshooting.

sqlcmd -S 10.132.0.2 -U sa -P "$SA_PASSWORD" -d data-pipeline -Q "SELECT 1" -l 10
-----------
          1
 
(1 rows affected)

Step 5 — check GCP firewall rules

If Step 3 times out, there is no application-level fix — the firewall must allow the port first. The command below lists all ingress rules and their allowed ports.

gcloud compute firewall-rules list --filter="direction=INGRESS" --format="table(name,network,direction,allowed,sourceRanges)"
NAME                    NETWORK  DIRECTION  ALLOW         RANGES
allow-sql-internal      default  INGRESS    tcp:1433      10.0.0.0/8
allow-ssh               default  INGRESS    tcp:22        0.0.0.0/0
default-allow-internal  default  INGRESS    tcp,udp,icmp  10.128.0.0/9

Linux | the “works from my machine” problem

If a pipeline fails to connect but a manual test from the same VM succeeds, the failure is not network-level — it is environmental. Four causes account for the vast majority of these cases.

"Works from my machine" — four hidden differences

  1. User context: The manual test runs as your user; the pipeline runs as a service account or container user. Different users may have different network namespaces (Docker), proxy settings (http_proxy env var), or firewall policies.
  2. DNS: Your /etc/hosts may resolve the hostname to a local entry that the pipeline container does not have.
  3. Connection pool exhaustion: The pipeline may have consumed all available connections. Check with SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process = 1.
  4. TCP keepalive: Idle connections through a load balancer or NAT gateway are silently dropped after a timeout (often 5 minutes on GCP). The pipeline holds a stale connection handle that the network has already closed. Fix: set the connection pool’s idle timeout lower than the NAT timeout.

Isolate the environmental difference

Run the connection test as the same user and inside the same network namespace as the pipeline. For Docker-based pipelines: docker exec -it <container> nc -zv <host> <port>. Compare the results to your manual test.

PowerShell connectivity testing tools

This section covers the PowerShell-native equivalents: Test-NetConnection for TCP port testing and route tracing, Resolve-DnsName for DNS queries, and Get-NetTCPConnection for inspecting local listening sockets. These cmdlets are available on all supported Windows versions and in PowerShell 7+ on Linux.

PowerShell | Test-NetConnection | port reachability

Test-NetConnection is the primary PowerShell cmdlet for testing TCP connectivity. It returns a structured object with TcpTestSucceeded, SourceAddress, RemoteAddress, and PingSucceeded properties, making it suitable for both interactive debugging and scripted checks.

Test whether a port is open

The cmdlet prints a formatted summary to the console and returns the result object to the pipeline. TcpTestSucceeded: True confirms that the three-way TCP handshake completed.

Test-NetConnection -ComputerName hostname -Port 1433
ComputerName     : hostname
RemoteAddress    : 10.132.0.2
RemotePort       : 1433
InterfaceAlias   : Ethernet
SourceAddress    : 10.142.0.5
TcpTestSucceeded : True

Extract the boolean result for use in scripts

Suppressing warnings with -WarningAction SilentlyContinue prevents the cmdlet from printing “WARNING: TCP connect to (hostname : 1433) failed” on a refused connection, which would pollute script output. The parentheses force evaluation before accessing the property.

(Test-NetConnection -ComputerName 10.132.0.2 -Port 1433 `
    -WarningAction SilentlyContinue).TcpTestSucceeded
True

Test-NetConnection is slow for bulk port sweeps

Each call has a built-in connection timeout. Sweeping ten ports with Test-NetConnection can take 30+ seconds if any are unreachable.

Use TcpClient for faster programmatic checks

The [System.Net.Sockets.TcpClient] class connects immediately and throws on failure with a configurable timeout, making it the correct choice for scripted sweeps:

$client = New-Object System.Net.Sockets.TcpClient
$result = $client.BeginConnect('hostname', 1433, $null, $null)
$success = $result.AsyncWaitHandle.WaitOne(3000, $false)
$client.Close()
$success
Flag / ParameterSyntaxDescription
-ComputerName-ComputerName hostnameTarget hostname or IP address
-Port-Port 1433TCP port to test; enables TCP test mode
-TraceRoute-TraceRoutePerform a traceroute instead of a port test
-Hops-Hops 20Maximum hops for traceroute (default 128)
-InformationLevel-InformationLevel QuietSuppress console output; return only the object
-WarningAction-WarningAction SilentlyContinueSuppress warning messages on failed connections

PowerShell | Resolve-DnsName | DNS resolution

Resolve-DnsName is the PowerShell equivalent of dig. It returns structured objects with Name, Type, IPAddress, and TTL properties, which can be filtered and piped without parsing text output.

Look up the IP address of a hostname

Without specifying a record type, the cmdlet returns all records found, including CNAME chains resolved to their final A or AAAA records.

Resolve-DnsName hostname
Name                           Type   TTL   Section    IPAddress
----                           ----   ---   -------    ---------
hostname                       A      300   Answer     10.132.0.2

Query a specific record type

Passing -Type constrains the query to a single record type, matching dig hostname A behavior.

Resolve-DnsName hostname -Type A
Name                           Type   TTL   Section    IPAddress
----                           ----   ---   -------    ---------
hostname                       A      300   Answer     10.132.0.2

Query a specific DNS server

-Server overrides the system resolver and directs the query to a specific nameserver — the equivalent of dig @8.8.8.8 hostname.

Resolve-DnsName hostname -Server 8.8.8.8
Name                           Type   TTL   Section    IPAddress
----                           ----   ---   -------    ---------
hostname                       A      299   Answer     203.0.113.10
ParameterSyntaxDescription
-Name-Name hostnameHostname or IP to resolve
-Type-Type ADNS record type: A, AAAA, CNAME, MX, TXT, NS, SOA
-Server-Server 8.8.8.8Use a specific DNS server instead of the system resolver
-DnsOnly-DnsOnlyUse DNS only; skip LLMNR and NetBIOS fallback
-NoHostsFile-NoHostsFileSkip the local hosts file during resolution

PowerShell | Test-NetConnection -TraceRoute | path tracing

Test-NetConnection with -TraceRoute performs a hop-by-hop trace to the destination. The result object contains a TraceRoute property with the IP address of each hop.

Trace the route to a host

Test-NetConnection -ComputerName hostname -TraceRoute
ComputerName   : hostname
RemoteAddress  : 10.132.0.2
TraceRoute     : {10.142.0.1, 172.16.0.1, 10.132.0.2}

Extract only the hop list

(Test-NetConnection -ComputerName hostname -TraceRoute).TraceRoute
10.142.0.1
172.16.0.1
10.132.0.2

PowerShell | Get-NetTCPConnection | local listening ports

Get-NetTCPConnection is the PowerShell equivalent of ss -tlnp. It reads TCP socket state from the system and can be joined with Get-Process to map each socket to a process name.

List all listening sockets with process names

The @{N='Process';E=...} calculated property looks up the process name by PID, producing a combined view equivalent to ss -tlnp.

Get-NetTCPConnection -State Listen | Sort-Object LocalPort |
    Select-Object LocalPort, OwningProcess,
    @{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}}
LocalPort OwningProcess Process
--------- ------------- -------
     1433          1234 sqlservr
     5432          5678 postgres
     6379          9012 redis-server

Filter to a specific local port

Get-NetTCPConnection -State Listen -LocalPort 1433 |
    Select-Object LocalAddress, LocalPort, OwningProcess,
    @{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}}
LocalAddress LocalPort OwningProcess Process
------------ --------- ------------- -------
0.0.0.0           1433          1234 sqlservr
ParameterSyntaxDescription
-State-State ListenFilter by socket state: Listen, Established, TimeWait, CloseWait
-LocalPort-LocalPort 1433Filter to sockets bound to the specified local port
-RemotePort-RemotePort 443Filter to connections targeting the specified remote port
-LocalAddress-LocalAddress 127.0.0.1Filter by local IP address
-OwningProcess-OwningProcess 1234Filter by PID

PowerShell | systematic debugging walkthrough

The PowerShell debugging sequence mirrors the Linux walkthrough, working up from DNS to application authentication.

Step 1 — resolve the hostname

Resolve-DnsName data-pipeline-sql -Type A
Name                           Type   TTL   Section    IPAddress
----                           ----   ---   -------    ---------
data-pipeline-sql              A      300   Answer     10.132.0.2

Step 2 — test the TCP port

Test-NetConnection -ComputerName 10.132.0.2 -Port 1433
ComputerName     : 10.132.0.2
RemoteAddress    : 10.132.0.2
RemotePort       : 1433
TcpTestSucceeded : True

Step 3 — verify local socket is listening (on the server)

Get-NetTCPConnection -State Listen -LocalPort 1433 |
    Select-Object LocalAddress, LocalPort,
    @{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}}
LocalAddress LocalPort Process
------------ --------- -------
0.0.0.0           1433 sqlservr

Step 4 — check Windows Firewall rules

If Test-NetConnection times out from a remote client, verify that Windows Firewall is not blocking the port on the server side.

Get-NetFirewallRule -Direction Inbound -Enabled True |
    Where-Object { $_.DisplayName -match "SQL" } |
    Get-NetFirewallPortFilter |
    Select-Object LocalPort, Protocol
LocalPort Protocol
--------- --------
1433      TCP

For a broader systematic diagnosis approach that goes beyond network connectivity into application and query-level troubleshooting, see troubleshooting-flowcharts.

Warnings

Generic probes can mislead

Three common false signals appear during connectivity testing:

  • ICMP reachability is not TCP reachability. Many cloud VMs and corporate firewalls block ICMP. A host that does not respond to ping may still be fully reachable on HTTP, SSH, or database ports.
  • curl exit code 0 is not HTTP success. curl https://api.example.com/data exits successfully even when the server returns 404 or 500, unless you opt into failure-on-HTTP-error behavior.
  • DNS answers may be cached. dig can show the current authoritative record while your application or workstation still uses an older cached IP until TTL expiry.

A green or red result from the wrong probe is not enough to prove the path is healthy or broken.

Match the probe to the protocol

Use the check that proves the exact layer you care about:

  • TCP reachability. Test the real port with nc -zv host port or Test-NetConnection -Port.
  • HTTP success. Use curl -sf -o /dev/null -w '%{http_code}' https://endpoint/health so transport success and HTTP success are not conflated.
  • DNS changes. Compare dig output with the local resolver view, and flush caches with systemd-resolve --flush-caches on Linux or Clear-DnsClientCache on PowerShell when validating a recent change.

The recommendations table below applies the same rule to the common day-to-day diagnostics.

Recommendations

ScenarioRecommendation
Basic reachabilityping -c 4 <host> (Linux) or Test-NetConnection <host> (PowerShell).
TCP port testnc -zv <host> <port> (Linux) or Test-NetConnection <host> -Port <port> (PowerShell).
DNS lookupdig +short <hostname> for scriptable output. nslookup <hostname> for quick interactive checks.
Network path diagnosistraceroute <host> (Linux) or Test-NetConnection <host> -TraceRoute (PowerShell).
HTTP endpoint testcurl -sf -o /dev/null -w '%{http_code}' https://endpoint/health for status code only.
Firewall rule verificationTest the specific port from the source machine. nc -zv for TCP; nmap -sU -p <port> for UDP.

Troubleshooting

SymptomLikely causeFix
ping succeeds but TCP connection failsFirewall blocks the specific port. Host is reachable at network layer but the service port is not open.Check firewall rules: ufw status, iptables -L, or GCP VPC firewall rules.
”Connection refused”The host is reachable but no process is listening on the target port.Verify the service is running: ss -tlnp | grep <port> or Get-NetTCPConnection -LocalPort <port>.
”Connection timed out”Firewall is silently dropping packets (no ICMP unreachable response).Check intermediate firewalls, security groups, and VPC rules. Use traceroute to identify where packets are dropped.
DNS resolves to wrong IPStale DNS cache, or DNS record not yet propagated.Flush cache: systemd-resolve --flush-caches. Check authoritative DNS: dig @8.8.8.8 <hostname>.
traceroute shows * * * at every hopICMP is blocked along the entire path.Use TCP traceroute: traceroute -T -p 443 <host> to trace using TCP SYN packets instead of ICMP.

Cross-references