Community topic cross ref:
- https://community.n8n.io/t/digestauth-not-working-w…ith-ip-cameras/199014
## Describe the problem/error/question
When trying to authenticate a request from HTTP Request node using Digest Auth, I experience "Unauthorized Access" even though correct credentials are used and the same request appears to go through with Code node, curl and browser.
## What is the error message (if any)?
General error:
```
Authorization failed - please check your credentials
Unauthorized Access
```
From HTTP Request:
```
{
"error_code": 401,
"full_message": "401 - \"Unauthorized Access\"",
"request": {
"headers": {
"accept": "application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7",
"authorization": "**hidden**"
},
"method": "GET",
"uri": "http://digest-file-server:8000/get_file",
"gzip": true,
"rejectUnauthorized": true,
"followRedirect": true,
"resolveWithFullResponse": true,
"followAllRedirects": true,
"timeout": 300000,
"encoding": null,
"json": false,
"useStream": true,
"auth": {
"user": "user123",
"pass": "**hidden**",
"sendImmediately": false
}
}
}
```
Other info:
```
{
"item_index": 0,
"node_type": "n8n-nodes-base.httpRequest",
"node_version": "4.2 (Latest)",
"n8n_version": "1.113.3 (Self Hosted)",
"time": "10/4/2025, 12:35:12 PM",
"stack_trace": "NodeApiError: Authorization failed - please check your credentials at ExecuteContext.execute (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-nodes-base@file+packages+nodes-base_@[email protected]_asn1.js@5_afd197edb2c1f848eae21a96a97fab23/node_modules/n8n-nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts:847:16) at processTicksAndRejections (node:internal/process/task_queues:105:5) at WorkflowExecute.executeNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@[email protected]_@[email protected]_08b575bec2313d5d8a4cc75358971443/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1265:8) at WorkflowExecute.runNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@[email protected]_@[email protected]_08b575bec2313d5d8a4cc75358971443/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1446:11) at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@[email protected]_@[email protected]_08b575bec2313d5d8a4cc75358971443/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1847:27 at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@[email protected]_@[email protected]_08b575bec2313d5d8a4cc75358971443/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:2461:11"
}
```
## Please share your workflow/screenshots/recording
```
{
"nodes": [
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-1248,
-432
],
"id": "31ebb697-d0c6-4327-ac0a-c3de6924025c",
"name": "When clicking ‘Execute workflow’"
},
{
"parameters": {
"jsCode": "const crypto = require('crypto');\nconst http = require('http');\nconst https = require('https');\nconst { URL } = require('url');\n\nfunction httpRequestBuffer(urlStr, { method = 'GET', headers = {}, timeoutMs = 5000 } = {}) {\n return new Promise((resolve, reject) => {\n const u = new URL(urlStr);\n const isHttps = u.protocol === 'https:';\n const lib = isHttps ? https : http;\n\n const req = lib.request(\n {\n protocol: u.protocol,\n hostname: u.hostname,\n port: u.port || (isHttps ? 443 : 80),\n path: u.pathname + (u.search || ''),\n method,\n headers,\n },\n (res) => {\n const chunks = [];\n res.on('data', (c) => chunks.push(c));\n res.on('end', () => {\n const body = Buffer.concat(chunks);\n const headersLower = {};\n for (const [k, v] of Object.entries(res.headers)) {\n headersLower[k.toLowerCase()] = v;\n }\n resolve({ status: res.statusCode, headers: headersLower, body });\n });\n }\n );\n\n req.on('error', reject);\n req.setTimeout(timeoutMs, () => req.destroy(new Error(`Request timeout after ${timeoutMs}ms`)));\n req.end();\n });\n}\n\nfunction parseDigestChallenge(www) {\n const out = {};\n const re = /(\\w+)=(\"([^\"]+)\"|([^\\s,]+))/g;\n let m;\n while ((m = re.exec(www)) !== null) {\n out[m[1]] = m[3] || m[4] || '';\n }\n return out;\n}\n\nasync function getDigestProtected(url, username, password) {\n const r1 = await httpRequestBuffer(url, { method: 'GET', headers: {}, timeoutMs: 5000 });\n if (r1.status !== 401) throw new Error(`Expected 401 challenge, got ${r1.status}`);\n\n const www = Array.isArray(r1.headers['www-authenticate'])\n ? r1.headers['www-authenticate'][0]\n : r1.headers['www-authenticate'];\n if (!www || !String(www).toLowerCase().startsWith('digest')) {\n throw new Error('No digest challenge received');\n }\n\n let sessionCookie = '';\n const setCookie = r1.headers['set-cookie'];\n if (setCookie) {\n const first = Array.isArray(setCookie) ? setCookie[0] : setCookie;\n sessionCookie = (first || '').split(';')[0]; // \"session=....\"\n }\n\n const c = parseDigestChallenge(www);\n const u = new URL(url);\n const method = 'GET';\n const uri = u.pathname + (u.search || '');\n\n const qop = (c.qop || 'auth').split(',')[0].trim();\n const nc = '00000001';\n const cnonce = crypto.randomBytes(8).toString('hex');\n\n const ha1 = crypto.createHash('md5').update(`${username}:${c.realm}:${password}`).digest('hex');\n const ha2 = crypto.createHash('md5').update(`${method}:${uri}`).digest('hex');\n const response = crypto\n .createHash('md5')\n .update(`${ha1}:${c.nonce}:${nc}:${cnonce}:${qop}:${ha2}`)\n .digest('hex');\n\n let authHeader =\n `Digest username=\"${username}\", realm=\"${c.realm}\", nonce=\"${c.nonce}\", uri=\"${uri}\", ` +\n `response=\"${response}\", qop=${qop}, nc=${nc}, cnonce=\"${cnonce}\", algorithm=MD5`;\n if (c.opaque) authHeader += `, opaque=\"${c.opaque}\"`;\n\n const headers = { Authorization: authHeader };\n if (sessionCookie) headers['Cookie'] = sessionCookie;\n\n const r2 = await httpRequestBuffer(url, { method, headers, timeoutMs: 5000 });\n if (r2.status !== 200) {\n const snippet = r2.body?.toString('utf8')?.slice(0, 200) || '';\n throw new Error(`Digest auth failed: ${r2.status} ${snippet}`);\n }\n\n return r2.body;\n}\n\nasync function run() {\n const url = $json.url;\n const username = 'user123';\n const password = 'pass123';\n\n try {\n const buf = await getDigestProtected(url, username, password);\n\n return [\n {\n json: {},\n binary: {\n file: {\n data: buf.toString('base64'),\n mimeType: 'image/png',\n fileName: 'example.png',\n fileExtension: 'png'\n },\n },\n },\n ];\n } catch (err) {\n return [\n {\n json: {\n error: true,\n message: (err && err.message) || String(err),\n },\n },\n ];\n }\n}\n\nreturn run();\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-800,
-528
],
"id": "16f5a9b8-d820-4fab-be82-d9f5ba89d489",
"name": "Code in JavaScript (works)"
},
{
"parameters": {
"url": "={{ $json.url }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpDigestAuth",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-800,
-336
],
"id": "187aa3a4-59e6-4cd5-8ad6-ddf408cc41b1",
"name": "HTTP Request (does not work)",
"credentials": {
"httpDigestAuth": {
"id": "6j0e6dn7ORWvPaEE",
"name": "Temp Test Credentials"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1580939f-5967-4ed7-b3ce-72d88130d4f9",
"name": "url",
"value": "http://digest-file-server:8000/get_file",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-1024,
-432
],
"id": "597fe6f9-d682-4688-9f8c-5384768d3fe7",
"name": "Set URL"
}
],
"connections": {
"When clicking ‘Execute workflow’": {
"main": [
[
{
"node": "Set URL",
"type": "main",
"index": 0
}
]
]
},
"Set URL": {
"main": [
[
{
"node": "HTTP Request (does not work)",
"type": "main",
"index": 0
},
{
"node": "Code in JavaScript (works)",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "9423335a0111216c302866f5fc1752af6da6042c706e1cc46ecd439bca874130"
}
}
```
Works in Code node:
<img width="2559" height="1324" alt="Image" src="https://github.com/user-attachments/assets/513dcf56-1b53-4a7b-8bb3-7452cd5c8caf" />
## Share the output returned by the last node
```
Problem in node ‘HTTP Request (does not work)‘
Authorization failed - please check your credentials
```
## Important:
In the workflow **above** I use http://digest-file-server:8000/get_file to reach the web server protected by the digest auth. This web server us running as a container in the same docker network.
In the examples **below** I use http://192.168.2.79:8800/get_file to reach the same web server through the port exposed on the host machine.
## CURL
```
curl --digest -u user123:pass123 --cookie-jar /dev/null -v http://192.168.2.79:8800/get_file -o download.png
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 192.168.2.79:8800...
* Established connection to 192.168.2.79 (192.168.2.79 port 8800) from 192.168.2.97 port 62710
* using HTTP/1.x
* Server auth using Digest with user 'user123'
> GET /get_file HTTP/1.1
> Host: 192.168.2.79:8800
> User-Agent: curl/8.16.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 401 UNAUTHORIZED
< Server: gunicorn
< Date: Sat, 04 Oct 2025 16:00:06 GMT
< Connection: close
< Content-Type: text/html; charset=utf-8
< Content-Length: 19
< WWW-Authenticate: Digest realm="Authentication Required",nonce="6c29aced533bf9632bf507844666aefa",opaque="f4690f2724f06298992b7240f0b99cf4",algorithm="MD5",qop="auth"
< Vary: Cookie
* Added cookie session=".eJwlyzEKgDAMQNG7ZHYIaRqNl5G0Nji1CnYS767i-OH9C6yf21JbzQVmkExquawxhOQqgZJHHCdmEbHiBsPv225H_wZnUXQaiR2FdFKl9AY6JtXsDPcDwMQcew.aOFEhg.j7iY02P5J8pMJWB5Ai6p8mNQYcw" for domain 192.168.2.79, path /, expire 0
< Set-Cookie: session=.eJwlyzEKgDAMQNG7ZHYIaRqNl5G0Nji1CnYS767i-OH9C6yf21JbzQVmkExquawxhOQqgZJHHCdmEbHiBsPv225H_wZnUXQaiR2FdFKl9AY6JtXsDPcDwMQcew.aOFEhg.j7iY02P5J8pMJWB5Ai6p8mNQYcw; HttpOnly; Path=/
<
0 19 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
* shutting down connection #0
* Issue another request to this URL: 'http://192.168.2.79:8800/get_file'
* Hostname 192.168.2.79 was found in DNS cache
* Trying 192.168.2.79:8800...
* Established connection to 192.168.2.79 (192.168.2.79 port 8800) from 192.168.2.97 port 62711
* using HTTP/1.x
* Server auth using Digest with user 'user123'
> GET /get_file HTTP/1.1
> Host: 192.168.2.79:8800
> Authorization: Digest username="user123", realm="Authentication Required", nonce="6c29aced533bf9632bf507844666aefa", uri="/get_file", cnonce="syH77nYMFb/7BbpJ", nc=00000001, qop=auth, response="3873f16d668b0f44b735b85d7f107b5b", opaque="f4690f2724f06298992b7240f0b99cf4", algorithm=MD5
> User-Agent: curl/8.16.0
> Accept: */*
> Cookie: session=.eJwlyzEKgDAMQNG7ZHYIaRqNl5G0Nji1CnYS767i-OH9C6yf21JbzQVmkExquawxhOQqgZJHHCdmEbHiBsPv225H_wZnUXQaiR2FdFKl9AY6JtXsDPcDwMQcew.aOFEhg.j7iY02P5J8pMJWB5Ai6p8mNQYcw
>
* Request completely sent off
< HTTP/1.1 200 OK
< Server: gunicorn
< Date: Sat, 04 Oct 2025 16:00:06 GMT
< Connection: close
< Content-Disposition: inline; filename=example.png
< Content-Type: image/png
< Content-Length: 269460
< Last-Modified: Fri, 03 Oct 2025 17:42:56 GMT
< Cache-Control: no-cache
< ETag: "1759513376.0043342-269460-828835327"
< Vary: Cookie
<
{ [13032 bytes data]
100 263k 100 263k 0 0 5339k 0 --:--:-- --:--:-- --:--:-- 5339k
* shutting down connection #19913
```
## BROWSER
<img width="1124" height="296" alt="Image" src="https://github.com/user-attachments/assets/6f16abb2-e1f5-4e10-a215-78cb3d924aa0" />
<img width="1455" height="1364" alt="Image" src="https://github.com/user-attachments/assets/2d7824a3-eae1-4552-b51b-2f53c2e2a17d" />
## Debug info
### core
- n8nVersion: 1.113.3
- platform: docker (self-hosted)
- nodeJsVersion: 22.19.0
- nodeEnv: production
- database: postgres
- executionMode: regular
- concurrency: -1
- license: enterprise (production)
### storage
- success: all
- error: all
- progress: false
- manual: true
- binaryMode: filesystem
### pruning
- enabled: true
- maxAge: 336 hours
- maxCount: 10000 executions
### client
- userAgent: mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gecko) chrome/140.0.0.0 safari/537.36
- isTouchDevice: false
Generated at: 2025-10-04T03:45:42.204Z