Azure Functions and forbidden sockets exception

What to do, when your Azure Function/Azure Web App application, after some time running, starts failing outgoing connections (e.g. HttpClient requests) on SocketException, but after restart your app starts to work.

1
2
3
System.Net.Sockets.SocketException
Exception while executing function Function1: An exception occurred while opening a connection to the server. 
An attempt was made to access a socket in a way forbidden by its access permissions.

The reason for this error is simple – you reached your’s sandbox (Project Kudu) currently opened outcoming sockets limit and sandbox disabled access for new sockets.

Azure connection limits

Limits per App Service Plans:

App Service PlanConnection Limit
Free F1250
Shared D1250
Basic B1 1 Instance1920
Basic B2 1 Instance3968
Basic B3 1 Instance8064
Standard S1 1 Instance1920
Standard S1 2 Instances1920 per instance
Standard S2 1 Instance3968
Standard S3 1 Instance8064
Premium P1 1 Instance (Preview)1920
Source: azurefieldnotes.com

How to solve this issue

Reason 1 – You really need so much connections

In case you really need so much connections opened at once, you have to upgrade you App Plan, according to limits table above.

Reason 2 – You have bug in you app

Check, if your application closes all the opened connections. For example in my application, source of this issue were not-released sockets by HttpClient.

How to use HttpClient (also) in Azure Functions/Web apps correctly

DON’T DO:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public static class HowToNotUseHttpClientInFunction
{
    [FunctionName("HowToNotUseHttpClientInFunction")]
    public static async Task Run(List urls, ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        foreach(var url in urls)
        {
            using (var client = new HttpClient())
            {
                var result = await client.GetAsync(url);
                Console.WriteLine(result.Content);
            }
        }

    }
}

Wrapping up HTTPClient into using() section will not work as you probably think – even the application exits, sockets stay to be opened and they will wait for OS’s timeout, after it can be reused. So in this case, function is going to allocate 10 sockets and will release them after timeout.

You can read more details on aspnetmonsters.com.

DO:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public static class HowToUseHttpClientInFunction
{
    public static HttpClient client = new HttpClient();

    [FunctionName("HowToUseHttpClientInFunction")]
    public static async Task Run(List urls, ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        foreach (var url in urls)
        {
            var result = await client.GetAsync(url);
            Console.WriteLine(result.Content);
        }

    }
}

This way will open only one connection and reuse it for all HTTP requests needed by application, so you will not probably reach Kudu’s limits.

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy