401 Unauthorized Access Error with SharePoint NTLM Authentication

Hafiz Hussain
2 min readJan 18, 2020


I am writing this post after I fixed an issue with SharePoint file upload APIs at one of our clients’ environment.

Note: The url, token and other API data I used in this article is either JUNK or generic parameters.

The problem was whenever I tried calling the file upload service http://hostname/repo_name/_api/web/getfolderbyserverrelativeurl('foldername')/files/add(overwrite=true, url=’test_file.docx’)

I got 401 Unauthorized Error.

The issue was, X-RequestDigest was going as null in the headers.

How do we get this RequestDigest?

Please go through this article, if you want to know what RequestDigest is


By calling the API http://{{sharepoint_hostname}}/{{project_name}}/_api/contextinfo

I achieved this with a simple .NET C# console application.

Simple .Net Console Application:

I am assuming the readers know how to create a simple .Net console application in MS Visual Studio. If not please visit the following link to create one.

In the Main function of the console app, I created a HTTP client get request with the following headers and parameters.

var uri = new Uri("http://{{sharepoint_hostname}}/{{project_name}}/_api/contextinfo");
var credentialsCache = new CredentialCache { { uri, "NTLM", new NetworkCredential("testusername", "testpassword", "") } };
var handler = new HttpClientHandler { Credentials = credentialsCache };
var httpClient = new HttpClient(handler) { BaseAddress = uri };
httpClient.DefaultRequestHeaders.ConnectionClose = false;
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "text/xml");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("DataServiceVersion", "3.0");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Host", "riskprocessuat.indusind.com");
ServicePointManager.FindServicePoint(uri).ConnectionLeaseTimeout = 120 * 1000; // Close connection after two minutes
var response = httpClient.PostAsync(uri, null).Result;
string respdata = await response.Content.ReadAsStringAsync();

For the given code, when the API is called, we get the request digest along with different parameters which looks some like this.

0xDAABCE0ABCDEF12345F589B1A1EABD258999CA8B225F96C944204AFA83813CF728FE7234F588E027FCB5BF9E21C3D06DBE1CFE7D19507AE687681E6A,19 Jan 2020 15:09:54 -0000 (Example JUNK Token)

With the above key as RequestDigest, I called the API to upload file to SharePoint with the following headers

"headers": {
"X-RequestDigest": "0xDAABCE0ABCDEF12345F589B1A1EABD258999CA8B225F96C944204AFA83813CF728FE7234F588E027FCB5BF9E21C3D06DBE1CFE7D19507AE687681E6A,19 Jan 2020 15:09:54 -0000",
"username": "testusername",
"password": "testpassword",
"Accept": "application/json;odata=verbose",
"Content-Length": "2",
"Content-Type": "text/plain"

When the service is called, I got response status as 200 instead of 401 Unauthorized and we were able to see the file at SharePoint site which we wanted to upload.

Please leave a comment, if there are any queries with this Authentication.