Testing IPv6 Connectivity by Hand: dig, ping6, curl, traceroute and What Each Command Actually Tells You
What happens when a user on an IPv6-only mobile network tries to reach your server and gets nothing back? You would never know unless you tested for it. IPv4 masks the problem because it still works. Your monitoring dashboard shows green. Your status page says "operational." But a growing fraction of real users sit behind carrier-grade NAT with IPv6 as their primary path to the internet, and for them, your service is down.
The gap between "IPv4 works" and "IPv6 works" is one of the most common blind spots in infrastructure operations. Fixing it starts with understanding what each manual test actually checks at the protocol level, how to read the output, and where manual testing falls short enough that automated monitoring becomes necessary. This guide walks through the full diagnostic toolkit: dig AAAA, ping6, curl -6, traceroute6, and more. Every command is explained not just in terms of syntax but in terms of what layer of the stack it validates and what a failure at that layer means.
Step 0: Confirm Your Own Machine Has IPv6
Before testing anything remote, verify your local machine actually has a working IPv6 address. Without one, every IPv6 test will fail regardless of the target's configuration, and you will chase the wrong problem.
On Linux, run:
ip -6 addr show scope global
You are looking for at least one address with scope global. Link-local addresses (starting with fe80::) do not count. They exist on every interface but cannot route to the internet. A valid global address will start with 2 or 3 (most commonly 2001:, 2a0-something, or a /64 from your ISP).
On macOS:
ifconfig en0 | grep inet6
On Windows:
ipconfig | findstr "IPv6"
If you have no global IPv6 address, the issue is your network, not the target. Common reasons: your ISP does not provision IPv6, your router has IPv6 disabled, or your OS has it turned off. Some ISPs provide IPv6 over DHCPv6 only on request. Others provide it through 6rd or DS-Lite tunneling. If you need to test IPv6 but your local network does not support it, you can set up a tunnel broker like Hurricane Electric's tunnelbroker.net, but that adds a variable that can confuse test results.
Step 1: DNS Resolution with dig AAAA
Every IPv6 connection begins with DNS. The client asks the resolver for an AAAA record (the IPv6 equivalent of an A record). If no AAAA record exists, IPv6 connections are impossible regardless of server configuration. This is the single most common IPv6 failure: nobody ever published the record.
dig AAAA example.com
The response you want looks like this:
;; ANSWER SECTION:
example.com. 3600 IN AAAA 2606:2800:21f:cb07:6820:80da:af6b:8b2c
What to check in the output:
- ANSWER SECTION present with at least one AAAA record. If the answer section is empty or says
NXDOMAIN, there is no IPv6 DNS entry. - The address looks correct. Compare it to what your hosting provider assigned. A stale AAAA record pointing to an old server is a common post-migration problem.
- TTL value. A very high TTL (86400 = 24 hours) means DNS changes propagate slowly. A very low TTL (60 seconds) suggests someone is actively making changes or using a CDN.
- SERVFAIL or timeout. This indicates a problem with your DNS server itself, not the AAAA record specifically.
For comparison, always check the A record too:
dig A example.com
If the A record exists but the AAAA does not, your site is IPv4-only. About 40% of mobile traffic now prefers IPv6 when available, so this is not a theoretical gap. You can also query a specific DNS server to rule out local resolver caching:
dig AAAA example.com @8.8.8.8
dig AAAA example.com @1.1.1.1
Differences between resolvers can reveal propagation issues or split-horizon DNS configurations.
On Windows, where dig is not installed by default, the equivalent is:
nslookup -type=AAAA example.com
Step 2: ICMP Reachability with ping6
DNS told you the address exists. Now test whether packets can actually reach it. ping6 sends ICMPv6 Echo Request packets and waits for Echo Reply. This tests Layer 3 reachability: can IP packets travel from your machine to the target and back?
ping6 -c 5 example.com
On some Linux distributions, ping handles both protocols automatically when given a hostname. You can force IPv6 explicitly:
ping -6 -c 5 example.com
On Windows:
ping -6 example.com
Reading the output:
- Replies with round-trip times. Success. IPv6 is routable end-to-end. Compare the latency with
ping -4 example.comto see if the IPv6 path is significantly longer (it sometimes is, especially with tunnel brokers). - "Network is unreachable." Your machine has no IPv6 default route. This is a local problem, not a remote one. Go back to Step 0.
- "Destination unreachable" or "No route to host." Your machine has IPv6, but something between you and the target cannot route the packet. Could be your ISP, a transit provider, or the target's network.
- 100% packet loss with no error message. Packets are being silently dropped. Likely a firewall blocking ICMPv6. Many cloud providers and hosting companies block ICMP by default on IPv6 even when they allow it on IPv4. This does not mean the server is down; it means ping is not a valid test for this particular target.
- High jitter (varying latency). The IPv6 path may be going through a tunnel or a congested transit link.
An important caveat: ping6 only tests ICMP. A host can respond to ping but have its web server, database, or application completely down. And a host can block ping while serving HTTP traffic perfectly. Ping is a necessary but not sufficient test. It confirms the network path exists; it says nothing about the application.
Step 3: Application-Layer Testing with curl -6
This is the test that matters most. curl -6 forces an HTTP(S) connection over IPv6. It tests DNS resolution, TCP connection, TLS handshake (for HTTPS), and HTTP response in a single command. If this succeeds, your service is reachable over IPv6 for real users.
curl -6 -I https://example.com
The -I flag fetches only headers, which is faster and gives you the response code without downloading the entire page. Typical output:
HTTP/2 200
content-type: text/html; charset=UTF-8
server: nginx
Failure modes and what they mean:
- "Could not resolve host." No AAAA record. Go back to Step 1.
- "connect() failed" or "Connection refused." The IPv6 address exists and is reachable at the network level, but no service is listening on that port. The web server might be bound only to the IPv4 address. Check your server configuration: nginx needs
listen [::]:443, Apache needsListen [::]:443. - "SSL certificate problem." The TLS certificate does not cover the hostname, or the server is presenting a different certificate on the IPv6 socket. This happens when the IPv6 address points to a different server (like a load balancer) that has its own certificate.
- Timeout. A firewall is blocking the TCP connection on port 443 (or 80) for IPv6. This is distinct from ping failing: the server might respond to ICMPv6 but block TCP/443 on its IPv6 interface.
- HTTP 4xx/5xx response. The connection works, but the application is returning an error. Compare with
curl -4 -I https://example.com. If IPv4 returns 200 but IPv6 returns an error, the application may be configured differently per address (virtual host misconfiguration, IP-based access control, etc.).
For deeper debugging, add -v for verbose output that shows every step of the connection:
curl -6 -v https://example.com 2>&1 | head -30
The verbose output shows DNS resolution, the TCP connect attempt, the TLS negotiation, and the HTTP exchange. Each step is prefixed with * for informational messages, > for request data, and < for response data. You can pinpoint exactly where the connection fails.
For timing data:
curl -6 -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" https://example.com
This breaks down the request into phases. Compare IPv6 timing with IPv4 timing to identify protocol-specific bottlenecks:
curl -4 -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" https://example.com
Step 4: Path Analysis with traceroute6
When ping or curl fails, traceroute6 tells you where in the network the failure occurs. It works by sending packets with incrementally increasing TTL (Time To Live, called Hop Limit in IPv6). Each router along the path decrements the hop limit and sends back an ICMPv6 "Time Exceeded" message when it hits zero. This maps the route hop by hop.
traceroute6 example.com
On Windows:
tracert -6 example.com
Typical output looks like this:
1 gateway (2001:db8::1) 1.234 ms 1.123 ms 1.089 ms
2 isp-router (2001:db8:1::1) 5.432 ms 5.321 ms 5.234 ms
3 * * *
4 transit-peer (2001:db8:2::1) 15.678 ms 15.543 ms 15.432 ms
5 target-dc (2606:2800:21f::1) 22.345 ms 22.234 ms 22.123 ms
6 example.com (2606:2800:21f:cb07:6820:80da:af6b:8b2c) 22.567 ms
Interpreting the results:
- Stars (* * *) in the middle. That hop's router is configured not to respond to traceroute probes. This is normal and not necessarily a problem. Many transit routers rate-limit or block ICMPv6.
- Stars at the end (last several hops). The target or its upstream provider is blocking traceroute. The packet may still reach the destination via TCP; traceroute just cannot map those final hops.
- Sudden latency jump. A jump from 5ms to 150ms between two hops indicates a long-distance link (e.g., crossing an ocean) or congestion on that link.
- Traceroute stops at a certain hop with no further responses. Traffic is being dropped at or near that point. This often indicates a firewall, a routing black hole, or a misconfigured router that does not have an IPv6 route to the destination.
- Different path than IPv4. Compare with
traceroute example.com(IPv4). IPv6 and IPv4 traffic often take completely different paths through the internet. One path might be congested or broken while the other works fine.
For TCP-based traceroute (useful when ICMP is blocked):
sudo traceroute6 -T -p 443 example.com
The -T flag uses TCP SYN packets instead of UDP or ICMP. Since firewalls generally allow TCP/443, this often maps more of the path than a default traceroute.
Step 5: TCP Port Testing with nc (Netcat)
Sometimes you need a targeted test: can a TCP connection be established to a specific port over IPv6? nc (netcat) is the right tool. It attempts a raw TCP connection without any protocol overhead.
nc -6 -zv example.com 443
nc -6 -zv example.com 80
nc -6 -zv example.com 25
The -z flag means "zero I/O mode" (just test the connection, do not send data). The -v flag provides verbose output. You will see either "Connection succeeded" or "Connection refused" / "Connection timed out."
This is particularly useful for testing non-HTTP services. Mail servers, database ports, game servers, custom APIs. If curl -6 works but your application users report IPv6 issues, the problem might be on a different port that only nc would reveal.
You can also test with an explicit IPv6 address instead of a hostname:
nc -6 -zv 2606:2800:21f:cb07:6820:80da:af6b:8b2c 443
This bypasses DNS entirely and tests pure network + port reachability.
The Complete Diagnostic Workflow
When you suspect IPv6 issues, work through these steps in order. Each step depends on the previous one succeeding. If a step fails, you have found the layer where the problem lives.
- Verify local IPv6.
ip -6 addr show scope global. No global address? Your local network is the problem. - Test against a known-good target.
ping6 -c 3 google.com. If this fails, your IPv6 internet connectivity is broken (ISP issue, router issue, or tunnel problem). - Check DNS.
dig AAAA your-domain.com. No AAAA record? Add one in your DNS provider. - Verify the address is correct. Compare the AAAA record against what your hosting provider shows as your server's IPv6 address. Stale records from old servers are a top cause of IPv6 failures.
- Ping the address directly.
ping6 -c 5 your-domain.com. Failure here (when google.com works) means a routing problem between your network and your server's network, or a firewall blocking ICMPv6 at the server end. - Test the application.
curl -6 -I https://your-domain.com. If ping works but curl fails, the server software is not listening on IPv6 or the firewall blocks the application port for IPv6. - Compare with IPv4. Run
curl -4 -I https://your-domain.com. If IPv4 works and IPv6 does not, you have isolated the issue to IPv6-specific configuration. - Trace the path if needed.
traceroute6 your-domain.comto find where packets are being dropped. - Test from another network. Use a VPS, a mobile phone on cellular, or a friend's connection. This rules out issues specific to your local network or ISP.
The Seven Most Common IPv6 Failures (and What Causes Them)
- No AAAA record. The domain has an A record but no AAAA. IPv6-only clients cannot reach you at all. Fix: add the AAAA record in DNS.
- AAAA points to wrong address. Common after server migrations. The old IPv6 address is still in DNS while the server has moved to a new one. Fix: update the record.
- Web server not bound to IPv6. The IPv6 address pings fine, but nginx/Apache is only listening on
0.0.0.0(IPv4). Fix: addlisten [::]:443 sslin nginx orListen [::]:443in Apache. - Firewall blocks IPv6 inbound.
iptablesrules exist for IPv4, butip6tableswas never configured. The default policy drops everything. Fix: mirror your IPv4 firewall rules toip6tablesor usenftableswhich handles both in one ruleset. - SSL certificate not served on IPv6 socket. The server has separate virtual hosts for IPv4 and IPv6. The IPv4 vhost has the correct certificate; the IPv6 vhost serves the default/wrong certificate. Fix: ensure the TLS certificate is configured for both sockets.
- CDN/proxy does not support IPv6. Your origin server has IPv6, but the CDN in front of it does not resolve AAAA or does not proxy IPv6 connections. Fix: enable IPv6 in your CDN settings (Cloudflare has this on by default; others may not).
- Partial IPv6 from hosting provider. The provider assigns an IPv6 address and it pings, but routing is unreliable. Certain ISPs cannot reach it. This is a BGP-level problem on the provider's side. Fix: contact the provider or switch to one with better IPv6 peering.
Where Manual Testing Runs Out
Manual tests answer the question "is it working right now, from where I am?" That is valuable for diagnosis. But it has hard limits:
- You test from one location. IPv6 routing issues are often path-specific. Your ISP's path to the server might work while a major transit provider used by 30% of your users has a broken route. Manual testing from your desk will never catch that.
- You test at one point in time. IPv6 issues can be intermittent. BGP route changes, temporary congestion, provider maintenance. A test that passes at 10 AM and fails at 2 PM looks fine if you only tested once in the morning.
- You have to remember to test. After a DNS change, a server migration, a firewall update, a provider maintenance window. Any of these can break IPv6 while leaving IPv4 intact. Will you remember to test IPv6 every time?
- You cannot test continuously. Even if you test daily, a 3-hour outage between tests goes undetected. Your users notice before you do.
- No historical data. Manual tests leave no record. You cannot prove that IPv6 was working last Tuesday or identify a pattern of failures every weekend.
What Automated Monitoring Adds
Automated monitoring with UptyBots runs the equivalent of these manual tests continuously, from multiple locations, and records every result. The difference is not sophistication; it is persistence.
- Separate IPv4 and IPv6 monitors. Create independent checks for each protocol. When IPv6 goes down while IPv4 stays up, you get an alert specifically for the IPv6 failure. No guessing which protocol broke.
- Multi-location testing. Checks run from different geographic regions, catching path-specific routing failures that single-point testing misses.
- Continuous intervals. Checks every 1 to 5 minutes, 24/7. An IPv6 outage at 3 AM on Sunday gets detected just as fast as one during business hours.
- Instant alerts. Notifications via email, Telegram, or webhook the moment a check fails. No delay between failure and awareness.
- Historical records. Full history of response times and availability per protocol. You can track IPv6 latency trends over weeks and months, spot degradation before it becomes an outage, and prove SLA compliance with real data.
- Response time comparison. Side-by-side IPv4 vs IPv6 latency data shows when one protocol consistently underperforms, which can indicate routing problems or suboptimal peering.
The pattern for most teams: use manual commands to diagnose a specific issue, use automated monitoring to make sure the issue does not recur silently.
When to Combine Manual and Automated Testing
Manual testing and automated monitoring serve different purposes and complement each other:
- Initial setup. When deploying a new server or adding IPv6 for the first time, run through the full manual workflow (Steps 0-5) to verify everything before setting up automated monitoring.
- After infrastructure changes. Server migration, DNS changes, firewall updates, CDN reconfiguration. Run manual tests immediately to catch obvious breakage, then let automated monitoring verify stability over the following days.
- Investigating an automated alert. Monitoring tells you IPv6 is down. Manual tools tell you why. Use
digto check DNS,curl -6 -vto find the connection failure point,traceroute6to locate the network break. - Verifying a fix. After correcting a misconfiguration, manual tests give instant feedback. But keep the automated monitor running to confirm the fix holds over hours and days.
- Compliance and SLA reporting. Automated monitoring provides the historical data. Manual tests cannot substitute for this because they are not recorded, not continuous, and not from multiple locations.
Quick Command Reference
- ip -6 addr show scope global - Show local IPv6 addresses (Linux)
- dig AAAA example.com - Query IPv6 DNS record
- dig A example.com - Query IPv4 DNS record (for comparison)
- dig AAAA example.com @8.8.8.8 - Query via specific resolver
- nslookup -type=AAAA example.com - Windows equivalent of dig AAAA
- ping6 -c 5 example.com - ICMPv6 reachability (Linux/macOS)
- ping -6 example.com - Same on Windows
- curl -6 -I https://example.com - HTTP over IPv6 (headers only)
- curl -4 -I https://example.com - HTTP over IPv4 (for comparison)
- curl -6 -v https://example.com - Verbose connection trace over IPv6
- traceroute6 example.com - Trace IPv6 path (Linux/macOS)
- tracert -6 example.com - Same on Windows
- sudo traceroute6 -T -p 443 example.com - TCP-based traceroute
- nc -6 -zv example.com 443 - Test TCP port over IPv6
Frequently Asked Questions
Why does ping6 return "Network is unreachable"?
Your machine has no IPv6 default route. This means your local network does not support IPv6. Possible causes: ISP does not provision IPv6, router has IPv6 disabled, or the OS has it turned off. Run ip -6 route show default to confirm whether a default route exists.
ping6 works but curl -6 fails. What is wrong?
The network path works (ICMP gets through), but the application layer does not. Most likely: the web server is not listening on the IPv6 address (only bound to IPv4), or a firewall allows ICMPv6 but blocks TCP on port 80/443 for IPv6 traffic. Check your server's listen directives and firewall rules for both protocols.
Should I test IPv6 even if most of my users are on IPv4?
Yes. The share of IPv6 traffic is growing steadily and is already the majority on many mobile networks. If your DNS has an AAAA record, clients will attempt IPv6 first. A broken AAAA record is worse than no AAAA record because it causes connection delays (the client tries IPv6, times out, then falls back to IPv4). Either support IPv6 properly or remove the AAAA record entirely.
Can UptyBots monitor IPv6 endpoints separately?
Yes. UptyBots supports separate IPv4 and IPv6 monitors, so you can track each protocol independently. You will get protocol-specific alerts, response times, and uptime history.
How do I know if my CDN supports IPv6?
Run dig AAAA your-domain.com while your domain points to the CDN. If the CDN returns AAAA records, it supports IPv6. Cloudflare enables IPv6 by default. AWS CloudFront supports it but requires explicit enablement. Check your CDN's documentation for the specific toggle.
Start improving your uptime today: See our tutorials or choose a plan.