Troubleshooting CurlDotNet: fix common curl errors in C#
Troubleshooting CurlDotNet: fix common curl errors in C# by matching the symptom you see (timeout, DNS or connection failure, TLS certificate error, HTTP 401/404/429/500, invalid JSON, compile error) to the page that solves it. This hub explains which exceptions CurlDotNet throws, how to inspect a CurlResult, and which diagnostics to run before asking for help.
Quick Links
- Common Issues - the most frequent problems, each with a fix
- Error Reference - curl exit codes and the exception each one maps to
- FAQ - short answers to common questions
- Diagnostic Tools - verbose mode, result inspection, network checks
- Getting Help - where to ask
Find Your Problem
| Symptom | Category | Fix |
|---|---|---|
| Cannot install or set up | Installation | Installation Issues |
| Could not resolve host / connection refused | Network | DNS and Connection Errors |
| Request times out | Network | Timeout Errors |
| SSL certificate problem | Security | SSL Certificate Errors |
| 401 or 403 responses | Security | Authentication Errors |
| 404, 429, 500 responses | HTTP | HTTP Errors |
| JSON will not parse | Data | JSON Parsing Errors |
| Code will not compile | Development | Compilation Errors |
| NullReferenceException at runtime | Development | Runtime Errors |
Cannot write -o file / read -d @file |
Files | Transfer and file errors |
| Any other curl exit code | Reference | Error Reference |
Each section states the problem, the cause, the fix (code or commands) and how to prevent it.
Two Kinds of Failure
CurlDotNet separates transport failures from HTTP status codes, exactly as the curl command-line tool does:
- Transport failures throw, with curl’s exit code. A host that does not resolve throws
CurlCouldntResolveHostException(6), a refused connectionCurlCouldntConnectException(7), a TLS failureCurlSslConnectErrorException(35) orCurlPeerFailedVerificationException(60), an expired--max-timeor--connect-timeoutCurlOperationTimeoutException(28; catch its baseCurlTimeoutException), an unwritable-ofileCurlWriteErrorException(23). All derive fromCurlExceptioninCurlDotNet.Exceptions, andCurlErrorCodeholds the number. - HTTP 4xx and 5xx do not throw unless the command has
-f/--fail.ExecuteAsyncreturns aCurlResultwithIsSuccess == falseand theStatusCode. With-fit throwsCurlHttpReturnedErrorException(22), like curl; or callresult.EnsureSuccess()(CurlDotNet.Core.CurlHttpException). - Cancellation is standard .NET. A cancelled
CancellationTokenthrowsOperationCanceledException.
using CurlDotNet;
using CurlDotNet.Exceptions;
try
{
var result = await Curl.ExecuteAsync("curl -m 10 https://httpbin.org/status/503");
if (!result.IsSuccess)
Console.WriteLine($"HTTP {result.StatusCode}: {result.Body}");
}
catch (CurlTimeoutException ex) { Console.WriteLine($"Timed out: {ex.Timeout}"); }
catch (CurlCouldntConnectException ex) { Console.WriteLine($"No connection to {ex.Host}:{ex.Port}"); }
catch (CurlException ex) { Console.WriteLine($"curl error {ex.CurlErrorCode}: {ex.Message}"); }
Every CurlException carries Command, CurlErrorCode (the curl exit code, when known), StandardOutput (what curl would have printed before failing), Suggestions (a list of fix hints) and DiagnosticInfo. Its message says how to fix the problem. See the Error Reference for every exception type and code, and curl exit codes for the curl tool’s numbered list.
Diagnostic Tools
Enable verbose mode
The -v flag adds the request and response headers to the start of result.Body, the same information curl prints on the command line; --trace-ascii FILE writes a full trace:
var result = await Curl.ExecuteAsync("curl -v https://httpbin.org/get");
Inspect the result
using CurlDotNet;
var result = await Curl.ExecuteAsync("curl https://httpbin.org/get");
Console.WriteLine($"Status: {result.StatusCode}");
Console.WriteLine($"Success: {result.IsSuccess}");
Console.WriteLine($"Content-Type: {result.GetHeader("Content-Type")}");
Console.WriteLine($"Body length: {result.Body.Length}");
Console.WriteLine($"Total time (ms): {result.Timings?.Total}");
foreach (var header in result.Headers)
Console.WriteLine($"{header.Key}: {header.Value}");
result.Headers is case-insensitive; GetHeader returns null when the header is missing, so check HasHeader or test for null before using the value.
Validate the command before running it
var validation = Curl.Validate("curl -X POST -H 'Content-Type: application/json' https://httpbin.org/post");
if (!validation.IsValid)
Console.WriteLine($"Invalid command: {validation.Error}");
Compare with the curl command line
If the same command works in a terminal but not in CurlDotNet, that is a bug worth reporting.
# Same request with native curl
curl -v https://httpbin.org/get
# Save the response to a file
curl -v https://httpbin.org/get -o response.txt
# Headers only
curl -I https://httpbin.org/get
Network diagnostics
# DNS resolution
nslookup api.github.com
# Reachability
ping api.github.com
# Is the port open?
nc -vz api.github.com 443
# TLS certificate details
openssl s_client -connect api.github.com:443 -servername api.github.com
.NET diagnostics
dotnet --version
dotnet --list-sdks
dotnet --list-runtimes
dotnet restore
dotnet clean && dotnet build
Debugging Checklist
Basic checks
- Does the URL open in a browser?
- Is the URL spelled correctly, including the scheme (
https://)? - Are you using the right HTTP method (
-X POSTand so on)? - Is the server running and reachable from this machine?
Authentication
- Does the endpoint need credentials?
- Is the token current, and sent in the header the API expects?
- Does the response include a
WWW-Authenticateheader that names the expected scheme?
Request configuration
- Are headers in
-H 'Name: value'form? - Is the body valid JSON or form data for the
Content-Typeyou send? - Are quotes inside the command string escaped (
\"or""in verbatim strings)? - Is
--max-timelong enough for the slowest expected response?
Response handling
- Are you checking
result.IsSuccessbefore readingresult.Body? - Are you catching
CurlException(or specific subclasses)? - Does
result.GetHeader("Content-Type")match what you parse?
Environment
- Is the .NET SDK installed and on
PATH? - Is the CurlDotNet package the latest version?
- Does a proxy or firewall block outbound HTTPS from this environment?
Troubleshooting Approach
Read the exception
CurlException.Message describes what went wrong; Suggestions lists likely fixes.
catch (CurlException ex)
{
Console.WriteLine(ex.Message);
foreach (var tip in ex.Suggestions)
Console.WriteLine($" - {tip}");
}
Catch specific exceptions first
try
{
var result = await Curl.ExecuteAsync("curl https://api.github.com");
result.EnsureSuccess();
}
catch (CurlCouldntConnectException ex) { Console.WriteLine($"Connection: {ex.Message}"); }
catch (CurlTimeoutException ex) { Console.WriteLine($"Timeout: {ex.Message}"); }
catch (CurlDotNet.Core.CurlHttpException ex) { Console.WriteLine($"HTTP {ex.StatusCode}"); }
catch (CurlException ex) { Console.WriteLine($"curl: {ex.Message}"); }
Simplify, then add back
Start with a request that should always work, then add headers, data and authentication one step at a time:
var r1 = await Curl.ExecuteAsync("curl https://httpbin.org/status/200");
var r2 = await Curl.ExecuteAsync("curl https://httpbin.org/get -H 'Accept: application/json'");
var r3 = await Curl.ExecuteAsync(@"curl https://httpbin.org/bearer \
-H 'Accept: application/json' \
-H 'Authorization: Bearer token'");
If https://httpbin.org/get and https://api.github.com work but your endpoint does not, the problem is specific to that endpoint or your configuration.
Getting Help
Before asking
- Search existing issues - the problem may already be solved.
- Read the relevant section of Common Issues.
- Run the same command with native curl in a terminal.
- Reduce your code to the smallest example that still fails.
Where to ask
- GitHub Discussions - questions and how-to
- GitHub Issues - bugs and feature requests
What to include in a bug report
- A clear title, for example “CurlCouldntConnectException for host that native curl reaches”.
- CurlDotNet version (
dotnet list package). - .NET version (
dotnet --version) and operating system. - The smallest code sample that reproduces the problem.
- The full exception message and stack trace.
- What you expected, what happened, and whether native curl behaves differently.
Quick Reference
# Clear the NuGet cache
dotnet nuget locals all --clear
# Restore packages
dotnet restore
# Add or update CurlDotNet
dotnet add package CurlDotNet
# Build with detailed output
dotnet build -v detailed
// Quick connectivity test
try
{
var result = await Curl.ExecuteAsync("curl -m 10 https://httpbin.org/status/200");
Console.WriteLine(result.IsSuccess ? "Connection OK" : $"HTTP {result.StatusCode}");
}
catch (CurlException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
Related Pages
- Common Issues - detailed solutions
- Error Reference - exit codes and exceptions
- FAQ - frequently asked questions
- Installation - setup help
- Handling Errors tutorial - step-by-step error handling
- Exception documentation - one page per exception family
- Cookbook - ready-to-use recipes