Jitsumi logo Jitsumi

PowerShell curl -H Errors: Check the Alias Before Changing Your API Request

A curl command fails in Windows PowerShell? Identify the Invoke-WebRequest alias, use curl.exe or translate the request to a PowerShell cmdlet.

Two abstract command paths lead from separate terminal-shaped panels into different execution routes, illustrating why curl can resolve to a PowerShell alias instead of the native tool.

TL;DR

  • In Windows PowerShell 5.1, curl is an alias for Invoke-WebRequest, so -H and -X fail.
  • Run Get-Command curl -All to confirm, then type curl.exe to use the real tool.
  • Parameter-binding errors are local; a 401 or TLS warning means curl did run.

A command copied from an API tutorial works in Command Prompt, but Windows PowerShell reports that -H cannot be converted into a dictionary or that -X is not a recognised parameter. The server may not have received a request at all.

In Windows PowerShell 5.1, `curl` normally points to `Invoke-WebRequest` rather than the curl executable. The two tools accept different options. To run the command-line curl tool in Windows PowerShell, explicitly type `curl.exe`. PowerShell 7+ does not define that alias by default, though customised shells can. Microsoft confirms both behaviours in its curl on Windows guide.

This guide covers Windows 10 and Windows 11 using Windows PowerShell 5.1, PowerShell 7+, or Command Prompt. It reflects the documentation available on 8 November 2026. The examples are documentation-verified rather than executed in a Windows PowerShell session.

The command-name collision

When a shell reads a command, it decides which executable, function or alias the name represents. In Command Prompt, curl generally selects the Windows curl binary. In Windows PowerShell 5.1, the built-in alias can take precedence and call Invoke-WebRequest. Windows Terminal can host either shell, so the window title by itself cannot tell you what is running.

Native curl expects a string after -H, such as "Content-Type: application/json". In contrast, PowerShell's Invoke-WebRequest -Headers expects a mapping of header names to values. The PowerShell 5.1 Invoke-WebRequest reference documents this parameter and the separate -Method option.

Consider this illustrative curl line:

curl -X POST https://api.example.com/items -H "Content-Type: application/json"

The hostname is a placeholder. If curl is an alias, PowerShell tries to bind -X and -H to a cmdlet. A parameter-binding error can appear before a network request is sent. Reinstalling a game, changing API credentials or lowering browser security is not an appropriate response.

Find out what curl means in your exact window

These commands only inspect the shell and its command resolution:

$PSVersionTable.PSVersion.ToString()
Get-Command curl -All | Format-Table CommandType, Name, Definition
Get-Command curl.exe

The first returns the *PowerShell engine version*, not the Windows release. The second shows candidates in precedence order. If it reports Alias curl -> Invoke-WebRequest, the collision is present. Microsoft's Get-Command documentation explains why the -All option helps with duplicate command names.

The last check asks whether a native curl.exe executable is available. Two additional checks are useful:

where.exe curl
curl.exe --version

The explicit .exe matters. Bare where can refer to a PowerShell alias. curl.exe --version should print information about the native program, independent of the curl alias. If the executable is missing, investigate its installation and the process's PATH; do not turn off script security settings.

Different Windows Terminal tabs can host different shells. Recheck in the tab that actually failed rather than assuming one terminal application's settings apply to every tab.

Diagnose the right failure

Symptom

What it usually means

Next check

`curl -H` cannot convert a string to a dictionary

The PowerShell alias is calling Invoke-WebRequest, whose Headers parameter needs a dictionary

Use Get-Command curl -All, then curl.exe

`curl -X` is not recognised

The cmdlet is parsing native curl's flags

Inspect the shell and command name before changing the request

`curl --version` does not print a version

curl resolves to an alias or function

Run curl.exe --version

A Script Execution Risk confirmation appears

Windows PowerShell 5.1 has entered Invoke-WebRequest's legacy HTML-parsing path

Use -UseBasicParsing on the cmdlet or call curl.exe

`curl.exe` cannot be found

No native executable was found through this session's path

Try Get-Command curl.exe and where.exe curl

HTTP 401 or a TLS error appears

The client ran and a separate network, authentication or trust issue remains

Inspect the response; keep TLS validation on

A parameter-binding error is a local shell issue. A returned HTTP 401, a server error, or a TLS certificate warning is not. Once you have selected the intended program, read its actual response instead of assuming that every problem mentioning curl has the same cause.

Use native curl when following curl documentation

If the original instructions use -I, -H, -X or --data-binary, the least surprising repair in Windows PowerShell is to spell the executable name:

curl.exe --version
curl.exe -I https://example.com/

The -I flag requests HTTP response headers. The example still needs connectivity, a trusted server certificate, and a server willing to respond. Microsoft's Windows curl page and the upstream curl manual document these commands.

Send JSON without fragile inline quotation marks

Linux shell recipes often contain single-quoted JSON strings. PowerShell's interaction with native argument parsing can make copying them harder than expected, particularly across versions. A file-based request avoids a layer of nested quoting. First make a tiny, ASCII-only demonstration file in a directory where you have write permission:

'{"name":"widget","quantity":1}' | Set-Content -LiteralPath .\request.json -Encoding ASCII

Get-Content -Raw -LiteralPath .\request.json

Inspect the content before the POST. The following is an illustrative template, not a working request; replace the API hostname with a test endpoint you control or are authorised to use:

curl.exe --request POST "https://api.example.com/items" `
  --header "Content-Type: application/json" `
  --data-binary "@request.json"

A backtick at the very end of a line continues a command in PowerShell. In Command Prompt, use one line or that shell's own continuation rules. The curl --data-binary documentation explains how it reads a file and sends its bytes without discarding line breaks.

Encoding warning: -Encoding ASCII is appropriate only for this deliberately ASCII sample. It cannot represent arbitrary Unicode. For multilingual production data, create and verify a valid UTF-8 request file with a suitable editor or no-BOM writer; Windows PowerShell 5.1 and PowerShell 7 do not handle every -Encoding option identically.

After checking your request, remove the disposable sample if you no longer need it:

Remove-Item -LiteralPath .\request.json

Curl completing a request is not proof the API accepted it. Inspect the HTTP status and any response body rather than mistaking all output for success.

Use PowerShell cmdlets when you want PowerShell behaviour

For scripted API calls, Invoke-RestMethod can be more convenient: it converts JSON responses to PowerShell objects. A simple GET looks like this:

$result = Invoke-RestMethod -Uri 'https://example.com/' -Method Get
$result

A sample POST uses a hashtable for headers and explicitly serialises the body:

$headers = @{ 'X-Request-Source' = 'manual-test' }
$body = @{ name = 'widget'; quantity = 1 } | ConvertTo-Json -Compress

Invoke-RestMethod -Uri 'https://api.example.com/items' `
  -Method Post `
  -Headers $headers `
  -ContentType 'application/json' `
  -Body $body

Again, replace the placeholder URL with your own API before executing. Here -Headers is a dictionary, -ContentType specifies JSON, and -Body contains JSON text. Microsoft's Invoke-RestMethod documentation explains automatic parsing and parameter behaviour. The basic syntax works for ordinary requests; advanced options may depend on the PowerShell version.

When the goal is downloading software, Invoke-WebRequest -OutFile can be a suitable cmdlet instead. If the publisher supplies an expected SHA-256 hash, verify the downloaded file before installing it. Jitsumi's Windows SHA-256 verification walkthrough shows how to check the complete hash. Matching a reference supports file-integrity checking; it does not establish that an unknown publisher is trustworthy.

A separate 2025 security prompt can confuse the issue

There is a newer complication for Windows PowerShell 5.1. With Windows updates released on or after 9 December 2025, Microsoft introduced a Script Execution Risk confirmation for the legacy HTML-parsing path in Invoke-WebRequest. Someone who thinks they invoked curl but actually invoked the alias can encounter that prompt unexpectedly.

Microsoft's security advisory originally published 9 December 2025 explains that the older path used Internet Explorer components that could execute page scripts. For genuine Invoke-WebRequest use, Microsoft's recommended safer approach is:

Invoke-WebRequest -Uri 'https://example.com/' -UseBasicParsing

In unattended Windows PowerShell 5.1 scripts, make that safe option explicit so a confirmation does not hold an automated job waiting for input. PowerShell 7 does not depend on the Internet Explorer HTML parser. Calling native curl.exe also avoids this specific cmdlet warning when the native program is what you intended. Do not blindly approve a warning simply to make a command finish.

Avoid changes that fix the wrong thing

A curl header-binding error does not require changing PowerShell execution policy. That policy concerns running scripts. For a .ps1 file blocked by an execution-policy error, Jitsumi has a separate PowerShell script-policy guide.

You also do not need to delete aliases permanently. Microsoft documents Remove-Item Alias:curl as a possible session-level workaround, but writing curl.exe is more explicit and does not change how other commands resolve in that window.

Do not add native curl's -k or --insecure switch to repair an alias error. Those flags turn off TLS certificate verification and can hide a separate certificate or trust problem. If curl.exe reports a genuine TLS error, investigate the reported cause while leaving verification on.

Avoid exposing real access tokens and passwords in pasted commands, shell history, screenshots and support tickets. Use a disposable test credential where possible, and redact secrets when sharing logs.

Check the outcome before moving on

After choosing a tool, rerun a harmless request and verify three things: command resolution identifies the intended program, the local parameter-binding error has disappeared, and the server's HTTP status and response body match expectations. If you now receive a 401 or TLS error, you have solved the alias issue but reached a different problem.

The distinction to remember is simple: `curl.exe` uses curl flags; `Invoke-WebRequest` and `Invoke-RestMethod` use PowerShell parameters.

Subscribe

All the new articles in one Monday digest. Unsubscribe with one click.

Share this post

Newsletter

The Monday edit from Jitsumi

All the new articles, in one Monday email. Leave with one click whenever you like.