PowerShell console loaded via the browser for troubleshooting Azure App Services API and network problems

Troubleshooting Azure App Services

Working with Azure App Services is great, but the usual tell-tale signs that something’s not working as expected – like your fans blowing at full speed and CPU ramping up to 100% – aren’t as immediately visible to developers when working in the cloud.

In this post, I’ll cover some of those “wish I’d known earlier” moments that have saved me huge amounts of time and frustration when troubleshooting Azure App Services API and network problems using the Kudu console. And not just issues with code, but useful tools available for diagnosing connectivity issues, verifying application behaviour, and even testing outbound API calls.

If you’re looking for detailed steps on how to debug code deployed to your App Service, check out my other post on Azure Kudu Diagnostics: CPU Spikes, Memory Leaks, Thread Pool Starvation and Full Dump Analysis.

What is Kudu Console?

Apart from being a rather stunning African antelope, Kudu console is the engine behind app services that allows you to manage, monitor, and debug various aspects of your source code deployments. Microsoft Learn offers a high-level overview, but there are several features especially useful for software and DevOps engineers, including:

  • Downloading IIS diagnostic dumps and Docker logs.
  • Viewing connection strings, environment variables, server variables, and HTTP headers.
  • Running commands via the integrated CMD and PowerShell debug consoles.

I’ll focus on the tools available in the consoles in this article, some of which aren’t immediately visible unless you know what to type and where to look.

Accessing the Kudu Console Endpoint

The first step in using the Kudu console and troubleshooting API and network problems is by visiting the .scm endpoint of your Azure App Service. Assuming you have access, visit the following URL in your browser:

  • https://<your-app-service-name>.scm.azurewebsites.net/

After logging in, you should see a page similar to the following:

Kudu console environment homepage for troubleshooting Azure App Services API and network problems

Once inside the Kudu console, use Debug Console > CMD or PowerShell to access the file system. This is where we’ll execute commands and use the following tools.

Check Endpoint Availability: tcpping

With so many access rules, restrictions, and firewalls to contend with, debugging connectivity quickly and easily can be a huge win. For example, you might have app services across different vnets and network security groups with tightly-controlled traffic flows. And when problems arise around connectivity between services, they may fail silently. If you’re lucky, you might get some indication from your logs and alerting.

Check whether an endpoint is available on a specific port:

tcpping jkrussell.dev:443

You’ll see the following messaging if the connection succeeds:

Connected to jkrussell.dev:443, time taken: 109ms
...
Complete: 4/4 successful attempts (100%). Average success time: 54.5ms

If there’s a failure on that port due to security configuration or access restriction, you’ll see the following:

PS C:\home> tcpping jkrussell.dev:19029

Connection attempt failed: Connection timed out.
...
Complete: 0/4 successful attempts (0%). Average success time: 0ms

You may see other similar errors, such as “No such host is known”, which can be indicative of issues with the endpoint you’re trying to reach caused by issues with DNS resolution.

Test API Calls: curl

Once you’ve validated connectivity in the Kudu console using tcpping, you’re ready to simulate real API requests from within the App Service environment using curl. This is a good check for ensuring that traffic is not restricted and any API subscription keys are working correctly. Examples of services you might use the following example with are:

Curl is a command-line tool that’s been around since 1998. It’s so useful that Microsoft incorporated it into their app service infrastructure for use cases just like ours – and if you don’t have it locally, download the executable to a local directory and make sure you add the folder to the PATH environment variable.

Is using curl the same in both CMD and PowerShell?
No. curl exists in both Kudu CMD and PowerShell consoles, but in PowerShell, curl is an alias for Invoke-WebRequest, which behaves very differently from the real curl. If you want to use curl in the PowerShell console, you must explicitly specify curl.exe.

Let’s first simply try calling an endpoint to see what kind of output we get. Open a CMD cloud console and run the following command:

curl --verbose https://jkrussell.dev

By specifying the --verbose flag, you’ll see the entire HTML output of the page, as well as any other metadata related to the request, such as other publicly-available details of the host and server:

      ...
   </body>
</html>

* ALPN: server accepted http/1.1
* using HTTP/1.x
> GET / HTTP/1.1

> Host: jkrussell.dev
> User-Agent: curl/8.9.1
> Accept: */*

* Request completely sent off
* schannel: failed to decrypt data, need more data
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Keep-Alive: timeout=5, max=100
< x-powered-by: PHP/8.2.27
< content-type: text/html; charset=UTF-8
< link: <https://jkrussell.dev/wp-json/>; rel="https://api.w.org/"
< transfer-encoding: chunked
< date: Fri, 11 Jul 2025 12:57:26 GMT

* Connection #0 to host jkrussell.dev left intact

This can be super useful if we’re checking to make sure our app service is reaching the desired destination. If configuration issues are stopping the connection succeeding, you may see access denied-type pages returned – a useful indicator that something is wrong that’s not your code.

Running a curl --help http will output the available flags to customise requests even further, should you need to. I’ve trimmed this list for brevity:

C:\home>curl --help http
Usage: curl [options...] <url>
http: HTTP and HTTPS protocol
...
 -b, --cookie <data|filename>          Send cookies from string/load from file
 -d, --data <data>                     HTTP POST data
 -G, --get                             Put the post data in the URL and use GET
 -I, --head                            Show document info only
 -H, --header <header/@file>           Pass custom header(s) to server
 -e, --referer <URL>                   Referrer URL
 -A, --user-agent <name>               Send User-Agent <name> to server
 
 For all options use the manual or "--help all".

Take note of one item buried deep inside that list that is rather useful to us: the –header (or “-H”):

-H, --header <header/@file>           Pass custom header(s) to server

It’s possible to send header values so that we can authenticate with an endpoint and make a real request. Replicating that kind of behaviour is a really rich tool because it provides us with an opportunity to test end-to-end. The request now becomes:

curl --verbose -H "Authorization: Bearer <token>" https://httpbin.org/get

To use different HTTP verbs like PUT, DELETE, or POST with curl, you use the -X flag (for “request method”) and optionally --data if the request includes a body:

curl --verbose -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/json" --data "{\"name\": \"John\"}" https://httpbin.org/post

Each HTTP method has a slightly different format, which you can find in the curl HTTP Scripting documentation.

Get Your App Service’s Outbound IP

If you do run into some issues of requests being blocked, a quick way to find the app service’s external IP is by using curl https://icanhazip.com, which will echo it back in the response.

Echo HTTP Requests Using HttpBin.org

You’ll spot that the above requests use endpoint https://httpbin.org/. It’s a free service that accepts requests and echoes them back in a response to you.

> curl --verbose -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/json" --data "{\"name\": \"John\"}" https://httpbin.org/post
...

* upload completely sent off: 16 bytes
{
  "args": {}, 
  "data": "{\"name\": \"John\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Authorization": "Bearer <token>", 
    "Content-Length": "16", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.9.1", 
    "X-Amzn-Trace-Id": "Root=1-687141f6-2156176853af91132a0e0088"
  }, 
  "json": {
    "name": "John"
  }, 
  "origin": "20.90.196.103", 
  "url": "https://httpbin.org/post"
}
< HTTP/1.1 200 OK

HttpBin.org is a great request and response tool with tons of useful features – check it out!

Managing Kudu Console Shell Output

If content scrolls too quickly, I always find that outputting to a log using > file.ext and viewing it separately is invaluable and stops you playing cat-and-mouse:

curl --verbose -H "Authorization: Bearer <token>" https://httpbin.org/get > c:\home\output.txt

The file will be saved to the directory you specify, and you can either download or open it separately:

CMD command shell in Kudu showing the location of the file output.txt.

Other Useful Kudu Console Shell Tools

If you found these useful, here are a few more tools worth exploring:

nslookup

Check DNS resolution for a hostname:

nslookup jkrussell.dev

tracert (CMD) / Test-NetConnection (PowerShell)

In the CMD shell:

tracert jkrussell.dev

And in PowerShell:

Test-NetConnection jkrussell.dev -Port 443

ping

Basic ICMP test (though often blocked):

ping jkrussell.dev

Leave a comment with your go-to shell commands – it’d be great to hear what you’re finding useful!

Final Thoughts

Next time you run into problems in one of your Azure App Services, make use of the tools shared in this post to up your game and resolve issues more quickly using the Kudu console.

Now you’ve mastered debugging network and connectivity issues, learn how to resolve issues in your production code in my follow up post: Azure Kudu Diagnostics: CPU Spikes, Memory Leaks, Thread Pool Starvation and Full Dump Analysis.

Leave a Reply

Your email address will not be published. Required fields are marked *