Forcing IPv4 or IPv6 connections with curl helps validate dual-stack deployments, compare performance between address families, and isolate routing or firewall issues. Restricting traffic to a single IP version exposes asymmetric paths and confirms that upstream services behave correctly when one family is preferred or required.
The curl client relies on the system resolver to translate hostnames into IP addresses and normally attempts connections in the order addresses are returned. Options such as --ipv4 and --ipv6 instruct curl to restrict connections to a specific address family, while HTTP semantics such as methods, headers, and payloads remain unchanged. Verbose and structured output options make it possible to see exactly which address was selected and how the handshake proceeded.
Using a single address family can reveal gaps such as missing AAAA records, broken IPv6 routing, or middleboxes that only handle IPv4. Some networks or servers offer no IPv6 support, so forcing --ipv6 can result in timeouts or resolution errors. When embedding these options into scripts, handling failures cleanly and providing fallbacks avoids unexpected outages when only one family is guaranteed to work.
Steps to force IPv4 or IPv6 connections in cURL:
- Request the current public address without forcing any IP version to observe the default behavior.
$ curl --silent http://api.example.net/ip | jq -r .origin 203.0.113.10
api.example.net echoes the source IP address that reaches the service and typically returns either a dotted-quad IPv4 address or a colon-separated IPv6 address.
- Force IPv4 connectivity by adding --ipv4 to the request.
$ curl --ipv4 --silent http://api.example.net/ip | jq -r .origin 203.0.113.10
The --ipv4 option restricts connections to IPv4 addresses even when DNS also supplies IPv6 records.
- Force IPv6 connectivity by adding --ipv6 to the request.
$ curl --ipv6 --silent --show-error http://api.example.net/ip { "origin": "2001:db8:100::10" }
Forcing IPv6 with --ipv6 fails when the local network, router, or remote host lacks working IPv6 connectivity, which usually produces connection timeouts or name resolution errors.
- Inspect the chosen address family and handshake details using verbose output.
$ curl --ipv4 --verbose --silent http://api.example.net/ * Host api.example.net:80 was resolved. * IPv6: (none) * IPv4: 127.0.0.1 * Trying 127.0.0.1:80... * Connected to api.example.net (127.0.0.1) port 80 ##### snipped #####
The line starting with Connected to shows the remote IP address, confirming whether IPv4 or IPv6 was selected.
- Verify the selected address family programmatically by printing only the remote IP address.
$ curl --silent --output /dev/null --write-out '%{remote_ip}\n' --ipv4 http://api.example.net/ 127.0.0.1 $ curl --silent --output /dev/null --write-out '%{remote_ip}\n' --ipv6 http://api.example.net/ 2001:db8:100::10
Success signals: the IPv4 command prints a dotted-quad address, the IPv6 command prints a colon-separated address when IPv6 connectivity is available, and failures return a non-zero exit status.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
