ApplicationInsights-node.js
ApplicationInsights-node.js copied to clipboard
ERR_HTTP_HEADERS_SENT
I'm using this module to track requests in a Node js Express App, running on an Azure web app.
The configuration for appInsights is at the top of my app.js file (which is the entry point to the app) and looks like this:
const appInsights = require('applicationinsights');
appInsights.setup(process.env.APP_INSIGHTS_KEY).setSendLiveMetrics(true).start();
I also have another Node js app (NodeBB) running on another Azure web app. NodeBB is accessible on the main app's URL's using a Proxy. The Configuration for this is as follows:
const proxy = require('http-proxy-middleware');
app.use(
'/forums',
proxy({
target: process.env.FORUM_URL,
changeOrigin: true,
ws: true,
})
);
This Proxy route definition is underneath the appInsights code in app.js.
When using NodeBB through the proxy on the primary Node js app, the following error is being thrown:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ClientRequest.setHeader (_http_outgoing.js:470:11)
at Function.Util.safeIncludeCorrelationHeader (/home/site/wwwroot/node_modules/applicationinsights/out/Library/Util.js:322:21)
at Function.AutoCollectHttpDependencies.trackRequest (/home/site/wwwroot/node_modules/applicationinsights/out/AutoCollection/HttpDependencies.js:131:22)
at clientRequestPatch (/home/site/wwwroot/node_modules/applicationinsights/out/AutoCollection/HttpDependencies.js:47:45)
at Object.https.request (/home/site/wwwroot/node_modules/applicationinsights/out/AutoCollection/HttpDependencies.js:69:13)
at Array.stream (/home/site/wwwroot/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:126:74)
at ProxyServer.<anonymous> (/home/site/wwwroot/node_modules/http-proxy/lib/http-proxy/index.js:81:21)
at middleware (/home/site/wwwroot/node_modules/http-proxy-middleware/lib/index.js:46:13)
at Layer.handle [as handle_request] (/home/site/wwwroot/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/site/wwwroot/node_modules/express/lib/router/index.js:317:13)
at /home/site/wwwroot/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/site/wwwroot/node_modules/express/lib/router/index.js:335:12)
at next (/home/site/wwwroot/node_modules/express/lib/router/index.js:275:10)
at expressInit (/home/site/wwwroot/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (/home/site/wwwroot/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/site/wwwroot/node_modules/express/lib/router/index.js:317:13)
This only seems to happen when editing a long post on NodeBB. Posts are written in markdown, which is sent to the server and the rendered preview is sent back and shown in a 'preview' textarea.
When a post is of a certain content-length, the above error throws and NodeBB no longer works.
A post of content-length 1023 bytes works, but 1024 bytes and above doesn't.
This problem only occurs when appInsights is turned on in the primary web app - when appInsights is off and the other moving parts (NodeBB & Proxy) are on, this problem doesn't occur.
Seems to be related to #516 but for a much smaller size (500 MB vs 1 KB). The try/catch added to fix that is not applied for this header. A temporary workaround could be to add this proxy domain to your list of appInsights.defaultClient.config.correlationHeaderExcludedDomains
, although this will disable all correlation to it. I will try to RCA this since we should always be setting these headers before the req/res goes out
I tried to add both the 'frontend' and NodeBB (proxy) URLs but that doesn't seem to have worked.
I added like this:
appInsights.setup(process.env.APP_INSIGHTS_KEY).setSendLiveMetrics(true).start();
appInsights.defaultClient.config.correlationHeaderExcludedDomains = [process.env.FRONTEND_URL, process.env.FORUM_URL];
Hi @markwolff, does the implementation of the 'correlationHeaderExcludedDomains' look correct in my above post?
If the above is correct (which isn't working as a solution), is there any other way to get around this problem?
Your setup looks fine (although you could try calling setup
, then setting the config, then calling .start()
. Is your url well-formatted? We use url.parse()
to grab the hostname from it and then regex it across all of the provided excluded domains.
You want this to return false. https://github.com/microsoft/ApplicationInsights-node.js/blob/a4f95cbb0e6c59456c9c3510a5acca8e5cbbaedd/Library/Util.ts#L233-L247
OK, I'll try and re-order to see if that works.
Doing a quick test, the last return true
from that function is firing, so I assume the URLs I'm passing 'correlationHeaderExcludedDomains' aren't what they should be?
This is correct. I'm curious why your urls are not falling into the regex.text(...)
conditional though
As a quick idea for why the regex test might fail, @danstaak what format are the URLs in FORUM_URL
and FRONTEND_URL
?
I believe for correlationHeaderExcludedDomains
the strings must be hostnames, with no protocol (eg. bing.com
is okay but https://bing.com
is not).
URL parse is run on incoming URLs to get the hostname, but the excluded domains are expected to already be domains and are not parsed to sanity check.
@OsvaldoRosado Ah, the URLs do have the protocols on them actually. I'll try them without and hope that works.
@markwolff @OsvaldoRosado I can confirm that adding the URLs without the protocol did in fact work, and I am not longer receiving the error explained in my first post.
Is this resolution long-term or is there something that needs to be updated in the wider module codebase?
Are there any downsides to setting 'correlationHeaderExcludedDomains'?
In #534 I added a try/catch around the setHeader causing this. I am not quite sure what is causing it to try to set the header after 1024 bytes, but resolving that on our end would be the long-term fix. By setting correlationHeaderExcludedDomains
, you lose distributed tracing of requests between your app and the domains listed in that array.
This issue is also affecting our codebase. Is there any shortterm planning for a fix or should we also use correlationHeaderExcludedDomains
in the meanwhile?