What you'll learn
To diagnose network problems like a professional. When your API returns 502, when CORS blocks you, or when "it works on my machine but not in production", you'll know exactly where to look.
By the end you'll have a mental and practical toolkit to solve the most common network problems.
Your toolkit
curl: The Swiss army knife
# Basic GET
curl https://api.example.com/health
# See response headers
curl -I https://api.example.com/health
# See full exchange (request + response)
curl -v https://api.example.com/health
# POST with JSON
curl -X POST \
-H "Content-Type: application/json" \
-d '{"name":"test"}' \
https://api.example.com/users
# With authentication
curl -H "Authorization: Bearer TOKEN" https://api.example.com/me
# Measure times
curl -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" \
-o /dev/null -s https://api.example.com
ping: Check connectivity
# Basic
ping google.com
# Only 4 packets
ping -c 4 google.com
# If fails: network or DNS problem
# If works: server responds to ICMP
nslookup / dig: DNS
# Resolve domain
nslookup api.example.com
# More detail with dig
dig api.example.com
# See specific records
dig api.example.com A # IPv4
dig api.example.com AAAA # IPv6
dig api.example.com CNAME # Alias
dig api.example.com MX # Mail servers
netstat / ss: Active connections
# See listening ports (Linux)
ss -tlnp
# See listening ports (Mac)
netstat -an | grep LISTEN
# See established connections
ss -tn
netstat -an | grep ESTABLISHED
Scenario 1: "My API returns 502"
Step 1: Verify the server responds
# First, verify DNS
nslookup api.example.com
# If fails: DNS problem
# Then, verify connectivity
ping api.example.com
# If fails: server down or firewall
# Finally, verify HTTP
curl -I https://api.example.com/health
Step 2: If using reverse proxy (Nginx)
# See Nginx logs
sudo tail -f /var/log/nginx/error.log
# Common errors:
# "upstream timed out" - backend too slow
# "connection refused" - backend not running
# "no live upstreams" - all backends down
Step 3: Verify the backend
# See if process is running
ps aux | grep node # or python, java, etc.
# See if listening on correct port
ss -tlnp | grep 3000
# See backend logs
docker logs my-app --tail 100
# Or if systemd
journalctl -u my-app -f
Most common cause
502 Bad Gateway almost always means:
1. Backend is not running
2. Backend listens on different port
3. Backend takes longer than Nginx timeout
Scenario 2: "CORS blocks me"
Understanding CORS
Your frontend: https://app.example.com
Your API: https://api.example.com
Browser: "Hey API, my origin is app.example.com"
API: "I don't know you, blocked"
Browser: "CORS error!"
Step 1: Check the exact error
Open DevTools > Console
Common errors:
- "No 'Access-Control-Allow-Origin' header" โ Missing header
- "not in the Access-Control-Allow-Origin list" โ Origin not allowed
- "Method PUT is not allowed" โ Method not allowed
Step 2: Verify headers with curl
# Simulate preflight OPTIONS
curl -X OPTIONS \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: POST" \
-I https://api.example.com/endpoint
# Look for these headers in response:
# Access-Control-Allow-Origin: https://app.example.com
# Access-Control-Allow-Methods: GET, POST, PUT, DELETE
# Access-Control-Allow-Headers: Content-Type, Authorization
Step 3: Configure the server
// Express.js
const cors = require('cors');
app.use(cors({
origin: 'https://app.example.com', // Or array of origins
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true // If using cookies
}));
Scenario 3: "SSL certificate fails"
Step 1: Verify the certificate
# See certificate details
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -text -noout
# See only dates
echo | openssl s_client -connect api.example.com:443 2>/dev/null | openssl x509 -dates -noout
# Expected output:
# notBefore=Jan 1 00:00:00 2024 GMT
# notAfter=Apr 1 00:00:00 2024 GMT
Common errors
| Error | Cause | Solution |
|---|---|---|
| certificate has expired | Expired cert | Renew with certbot |
| unable to verify | Incomplete chain | Include intermediate cert |
| hostname mismatch | Domain doesn't match | Check CN/SAN of cert |
| self-signed | Self-signed cert | Use Let's Encrypt |
Renew with Certbot
# See certificate status
sudo certbot certificates
# Renew manually
sudo certbot renew
# Renew specific domain
sudo certbot certonly -d api.example.com
Scenario 4: "Responses are very slow"
Step 1: Measure where latency is
curl -w "\n\
DNS: %{time_namelookup}s\n\
Connect: %{time_connect}s\n\
TLS: %{time_appconnect}s\n\
TTFB: %{time_starttransfer}s\n\
Total: %{time_total}s\n" \
-o /dev/null -s https://api.example.com/slow-endpoint
# Example output:
# DNS: 0.023s <- DNS resolution
# Connect: 0.045s <- TCP connection
# TLS: 0.120s <- TLS handshake
# TTFB: 2.500s <- Time to first byte (PROBLEM!)
# Total: 2.550s
Interpretation
If DNS is high: DNS resolver problem
If Connect is high: Network latency or server far away
If TLS is high: Certificate/crypto problem
If TTFB is high: Server takes long to process
If Total >> TTFB: Response too large
Step 2: Diagnose the backend
# See slow queries in PostgreSQL
SELECT query, calls, mean_time
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
# See active processes
SELECT pid, query, state, wait_event_type
FROM pg_stat_activity
WHERE state = 'active';
Cheat Sheet
Essential commands
| Command | Use |
|---|---|
curl -I URL | See response headers |
curl -v URL | See full exchange |
ping HOST | Verify connectivity |
nslookup DOMAIN | Resolve DNS |
dig DOMAIN | Detailed DNS |
ss -tlnp | Listening ports (Linux) |
netstat -an | Connections (Mac/Linux) |
traceroute HOST | Packet route |
Status codes
| Code | Meaning | Where to look |
|---|---|---|
| 400 | Bad Request | Malformed request |
| 401 | Unauthorized | Token/API key |
| 403 | Forbidden | Permissions |
| 404 | Not Found | Correct URL? |
| 429 | Rate Limited | Too many requests |
| 500 | Internal Error | Backend logs |
| 502 | Bad Gateway | Backend + proxy logs |
| 503 | Unavailable | Server overloaded |
| 504 | Gateway Timeout | Proxy timeout |
Next step
Practice these commands with your own services. When something fails, you'll have the tools to diagnose it.