HTTP & TLS Troubleshooting
Take a failing HTTPS request apart layer by layer: DNS, TCP, TLS, HTTP — and know which one broke.
- Time
- 50 min
- Level
- Intermediate
- Objectives
- 4 objectives
- Cost
- Free
Where this fits in the platform
This lab adds
- The ability to diagnose a broken certificate before it is public
Which lets you
—
Before you start
You will need
- curl
- openssl
- dig
- nc
You do not need these already — the lab environment below provides them.
You will be able to
- Inspect a certificate chain and its expiry from the command line
- Separate a TLS failure from an HTTP failure
- Read `curl -v` output as a sequence of layers
Cost — Free
— uses public endpoints and a local container.
Nothing to pay in the browser. Open the terminal runs this against a simulated cloud — the same API calls and the same commands, with no account and no bill. The figure above applies only if you build it in your own.
The scenario#
"The site is down." It returns a certificate error in one browser, works in another, and curl fails with something different again.
Each of those is a different layer, and the fix depends entirely on which one.
Hands-on environment
Run this lab in a real terminal, free and in your browser. The environment is temporary and yours alone — break it as much as you like.
Open the terminalOpens in Killercoda, in a new tab — keep this page open for the steps.
Run it on your own machine
Run this lab on your own machine. One command starts the environment, with everything the lab needs already installed:
You will need:
- docker
git clone https://github.com/EgyKode/EgyKode-lab.git
cd EgyKode-lab
./egykode start
./egykode shellYou need Docker and Git installed. Everything else runs inside the environment. The first start downloads it and takes a few minutes; later starts are seconds.
Not sure what you already have? Run: npm run doctor — it checks and changes nothing.
Anything you tick here is your own record. EgyKode cannot see inside that terminal, so the success criteria stay self-assessed even when the environment checks your work for you.
DNS
Step 1 of 5
The four layers, in order#
DNS -> TCP -> TLS -> HTTP
dig nc openssl curlcurl -v walks all four in one command, and its output is readable as exactly
that sequence:
curl -v https://egykode.com/ 2>&1 | head -20* Host egykode.com:443 was resolved. <- DNS worked
* Connected to egykode.com (52.84.143.46) <- TCP worked
* TLS handshake, Certificate (11): <- TLS in progress
* SSL certificate verify ok. <- TLS worked
> GET / HTTP/2 <- HTTP beginsWhichever line is missing is the layer that failed.
What you are proving: You can settle whether a name resolves before blaming anything above it
This step settles no success criterion on its own.
dig +short egykode.com
dig egykode.com | grep -A2 "ANSWER SECTION"A wrong-but-cached answer is the common case; the TTL in the answer tells you whether you are looking at cache or configuration.
What you are proving: You can prove a port is reachable independently of whether TLS succeeds
Marking this settles success criterion 4.
nc -vz egykode.com 443This proves reachability on its own. If nc connects and curl still fails,
the network is fine and the problem is TLS or above — which removes firewalls
and security groups from the investigation entirely.
What you are proving: You can read a certificate's subject, issuer and expiry from the command line, and say what a verification failure implies
Marking this settles success criteria 1 and 3.
echo | openssl s_client -connect egykode.com:443 -servername egykode.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
# Just the expiry, for a monitoring check
echo | openssl s_client -connect egykode.com:443 2>/dev/null \
| openssl x509 -noout -enddate
# The full chain the server actually sends
echo | openssl s_client -connect egykode.com:443 -showcerts 2>/dev/null | grep -c "BEGIN CERTIFICATE"-servername sets SNI. Without it a server hosting several sites returns its
default certificate, and you diagnose the wrong one.
The three failures you will meet:
| Message | Means | Fix |
|---|---|---|
certificate has expired | The dates have passed | Renewal automation stopped |
unable to get local issuer certificate | Chain incomplete | Server sends the leaf but not the intermediate |
certificate is not valid for <host> | Right cert, wrong name | Missing SAN entry |
The second is the subtle one: it works in browsers, which cache intermediates from previous sites, and fails in curl and in your application. "It works in Chrome" is not evidence the chain is complete.
What you are proving: You can separate an application error from a transport error in the response itself
This step settles no success criterion on its own.
curl -sI https://egykode.com/ | head -5
curl -s -o /dev/null -w 'code=%{http_code} tls=%{time_appconnect} total=%{time_total}\n' https://egykode.com/time_appconnect is when TLS finished. If it is close to time_total, the
handshake is your latency, not the application.
What you are proving: You can name which layer failed for a broken URL you have not seen before
Marking this settles success criterion 2.
curl -v https://expired.badssl.com/ 2>&1 | grep -i "certificate"
curl -v https://wrong.host.badssl.com/ 2>&1 | grep -i "certificate"
curl -v https://untrusted-root.badssl.com/ 2>&1 | grep -i "issuer"
curl -v https://self-signed.badssl.com/ 2>&1 | grep -i "self.signed"Read each error and name the layer before moving on. -k skips verification and
is useful to confirm the diagnosis — if -k works, the transport is fine and
the fault is purely certificate validation.
Works in the browser, fails in curl
Almost always an incomplete chain. The browser cached the intermediate from another site; curl did not.
SSL_ERROR_SYSCALL with no detail
The connection dropped during the handshake — often a middlebox, or the server rejecting the TLS version. Try --tlsv1.2.
Certificate looks correct but the name is wrong
You omitted -servername, so the server returned its default certificate.
nc connects but curl times out
The port is open and nothing is speaking HTTPS on it — check you are not hitting a plain HTTP port with https://.
Success criteria
0 of 4
The concept behind it
Phase complete · 02 The application, in containers
You can now: The application runs locally in production-shaped containers, behind a reverse proxy, over TLS.
Next phase
Lab 13 of 59 on the project path