-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
send() failed (32: Broken pipe) when performing HTTP POST to Immich #77
Comments
Hey 👋🏻 I have setup a similar setup environment and don't see to be experiencing the same issue. I am uploading a 3mb file as per your reddit thread I dont see any errors. Is CrowdSec / AppSec running locally to NPMPlus (on same host to reduce latency)? Could you provide the full nginx configuration that is generated by NPMplus as I am using nginx (since its the same code I dont want to spend time configuring NPMPlus since its the same lua code)
everything seems to be getting processed:
|
Yup, both Crowdsec and NPMPlus are running in docker containers on the same host. Part of the same docker-compose:
Immich is running on the same host as well, as a docker container. The config for that one is very standard with little to no customization. My proxy config in NPMPlus looks like this: Nothing in custom locations, and a regular certbot certificate to force enable HTTPS. My crowdsec.conf file is this:
The two bottom lines are currently commented out to make it work. If I uncomment them, it breaks with the broken pipe error message when uploading anything. |
I don't use Immich myself, but there seems to be an Issue with it, I already have 3 discussions about it with multiple people having the same issues: the issue is always related to appsec and immich and disabling appsec (or changing APPSEC_FAILURE_ACTION to passthrough) fixed it (modsec also needs to be disabled) — sometimes increasing the timeouts also fixed (at least for Nextcloud which had similar issues), so I increased the default timeouts, but the issue still seems to exist on new installations with the new timeouts. |
To hopefully contribute, I started discussion 1241 that @Zoey2936 linked above. It was suggested I post here answering the below questions so here we go: Is the deployment local or remote (VPS)? Local Is the domain being proxied by a CDN like cloudflare? For full transparency I do use a Cloudflare tunnel, but only for external connections. The tunnel isn't involved while on the LAN. Does it happen on upload like the OP or when you said when immich makes a backup? I am the OP in that thread. I believe the single image upload and backup feature are basically the same thing using the same endpoint. The backup feature just does it automatically and in batches. This is what happens when I attempt to upload (or backup) a single photo:
(Domain name changed for privacy and yes, I use a non-typical subnet) Disabling Appsec fixes the issue, albeit with the trade off of reduced security. Thanks. |
Hey, Do you know how big is the body of the request when you get this error ? Currently, the appsec will try to process any body it sees, regardless of the size, which will lead to issues (also tracked here: #71). I haven't performed any real tests to see where the actual limit is currently, but I guess anything over a few hundred MBs will trigger this error. Once #80 is merged (it includes a large refactoring of the code, so we have to wait for it), we plan to add additional configuration on how to handle large bodies (allow to set a maximum body size and whether to drop the request or just analyze the headers when it's over the limit). |
I just met this issue today with my own Ghost blog post editing. appsec will block me from time to time as I was editing posts. No solution found yet but fortunately saw this issue, for post editing I think the body is not huge at all as I just started. |
The photos are a couple of MB each and it does one request per photo, so definitely not in the few hundred MB territory. |
Having the same issue. Issue happens even when inside the LAN, so no cloudflare on anything else involved.
what could be causing the broken pipe between the appsec and the proxy? edit: Initially, the containers were on different docker networks, and communicating via ports exposed to the host.
|
Just so it doesnt seem like we are being a PITA about replication steps, I have setup NPMPlus using the steps outlined in the repo. I created a base immich deployment using immich setup, I then setup immich to be exposed locally via:
I then setup a local alias called I then proceed to upload an image of my cat which is
Note this is all done locally not over https as I dont have a spare domain and dont want to spend time spinning up a VPS as the TLS layer shouldnt impact this. also appsec is live cause a request to
Edit: just to ensure it nothing with TLS, I generated a self signed certificate so http2 is at play cause I think npm doesnt enable it unless their is a certificate and still struggling to replicate. |
@LaurenceJJones
I also tried adding this, but no luck:
|
One more thing, @LaurenceJJones
Does this mean that nginx lua component is having issues when talking to crowdsec's appsec agent? |
These are all set by npmplus, setting them twice causes more issues than anything else, also you should not use $http_host, $host is correct and the default used by npmplus
you need to set them in the modsec config file, not as nginx directives |
Thanks @Zoey2936
|
Broken pipe typically means that when the data (most likely the body) is being transmitted to the appsec port the connection is closed before the appsec server responded to the nginx request. Typically the nginx workers tries to pool the connections so I would be surprised if it running out of connecting ports but this depends on how much stuff you are hosting / or the machine is OOMing whilst trying to process the request. Edit: so check your free RAM / make sure you are not constricting the crowdsec container to limited resources as currently the appsec requests are processed in memory so if you upload a 50mb file it read 50mb into RAM/Heap allocation (this is something we need to allow you to configure the max upload size as @blotus pointed out). |
Ok, so the error occurs when the nginx worker is sending the data TO appsec. Gotcha.
Then, npmplus is trying to reach appsec via hostIP:7422 When i moved the proxy and crowdsec to the same docker network and pointed to appsec via containername:7422, the error changed from broken pipe to connection reset by peer
|
and with the connection reset, do you see any logs crowdsec side? also might be useful in this debug session :D if we can enable debug log on crowdsec side so there more to see. You can do this by setting:
|
Nothing
That would be ideal. Do you know exactly how i enable debug on crowdsec appsec? |
updated my comment to add how to enable debug |
Output of the crowdsec logs when the broken pipe happens. Nothing really stands out to me... https://gist.github.com/yurividal/93c11f79806972bb070dc095e44be4e4 |
I does write a LOT of log lines every single time. This entire log i uploaded was from simply taking one picture and opening immich. |
Could you try adding these options to the appsec cofnig and see if it improves:
However, the very odd thing is in your logs, it get the request and it states it returns the response 😕 |
Adding routines: 2 didn't help.
|
so it seems we never explicitly add logging to check if the response didnt encounter an error so my guess is there is an error there but it not currently logged, once we can get it merged, we can continue debugging if you point you container version to |
I'm happy to test with the :dev version. Just let me know when it is published. |
The dev image should be updated to include a log statement if the response failed to write back to the remediation, since its an |
@LaurenceJJones I captured all the logs from crowdsec container, and the word "unable" doesn't appear in any log! Yet, the error still happened and the nginx logs show the broken pipe message. |
i also tried running it without the debug level, since its an error message. In that case, there were no logs at all printed on the crowdsec container |
with the dev container can you run |
I also tried the direct container-to-container settings in npmplus appsec config, which again, changed the error to |
Just found another piece of interesting information: When I am outside my network, access is proxied via cloudflare. In that case, it works, and i don't see any error messages in the nginx logs about appsec. weird, but just thought i'd mention it here. |
I think this adds to the suspicion that appsec is being overwhelmed by the volume of data sent all at the same time. |
very very odd 😕 Imo, I would rather say since we can see appsec is processing the rules and is managing to send a response as we dont see the "unable to send response" in the log, it seems it something within nginx / lua code. Could you provide some specs on the machine like core count and stuff I can try to alter the VM locally to see if a more restricted spec causes issues as at the moment im running 4vcpu and 4gb RAM. |
Full specs of the machine running crowdsec and npm
Do you know if there is any way to enable further debugging on the lua side? |
Also, this is probably unrelated, but maybe worth the read: In this project, users were seeing broken pipe message when 2 components were communicating, if the body was too large and the connection is being closed without consuming the full body of the message. |
Yes you can enable further debugging within nginx if it compiled with the debug flag (nginx -V 2>&1 | grep -- '--with-debug') then you can define a debug log file:
I would only recommend to add this to the immich vhost as if added globally this will cause a shed ton of logs 😅 However, testing the nginx compiled with NPMPlus it is not compiled with the debug flag.
|
@LaurenceJJones how big are the videos you were testing the upload with? When an upload is being sent directly to nginx, it is sending the entire request and body to appsec. Appsec cannot handle such big body-size, and drops the connection without closing it. The lua component sees the connection being droped with no Connection: close header, and throws a broken pipe error. The reason why it might be working when going trough cloudflare (assuming file is less than 100m) is that cloudflare might actually be breaking the payload into smaller chunks. |
I was testing with 3mb files as well as 50mb files as per the OP issue was any upload size was causing an issue. Edit: just testing with 200mb and 600mb upload also and still no broken pipes for me so still very lost. |
Hey to keep thread updated, Zoey added the |
Hey Zoey managed to generate a build with the debug flag, when you get chance to continue debugging switch over to
then if we can get the logs, please note nginx debug is very very verbose so feel free to send the log to |
I saw the error, lets wait until its more stable before proceeding with debugging further |
Hey everyone. I managed to upgrade to the :develop branch, and enable the debug logs. but, to my surprise, the ISSUE IS GONE. So, not sure exactly what changed in the :develop version, but it seems to have fixed the issue. |
possible changes I could think of are theese two updates:
|
😕 is an understatement at the moment 😕 |
Yeah, kind of a bummer that we couldn't pin-point the exact cause. But, at least it seems to be fixed. Maybe we put this issue on pause, until Zoey updates the stable version of npmplus, and then more users can report if they still see the issue or not. |
I agree, I wont close it as there might be something hidden somewhere 👍🏻 Just note as @blotus said there is a major update coming in #80 which add a new feature, adds tests and streamlines the code. So once this is merged and NPMPlus is stable and upgrades to have the metrics then I will be happy to class as complete. Edit: also thank you @yurividal for your time in debugging and allowing us to use your environment as a test place to get to the not so bottom of this 😆 |
So just a ping to all, Zoey released a new update to latest, so if you can all try pulling down the latest and update whenever you can just confirm if this resolved your issue OR it was maybe a fluke resolve for some 😅 |
Hi, I've been lurking in this discussion in the past few weeks. I pulled the latest tag and unfortunately the problem is still present for me:
The files I'm trying to upload to immich are ~4MB photos taken from the camera app on my Samsung Galaxy S24. |
Could you add the debug log above |
Logs sent! |
Just a quick update, from the logs you sent:
So it manages to write 2mb to the appsec component then the pipe is broken (there another issue in appsec I raised, that if the remediation fails / cancels the request it does not propogate to the appsec so the appsec always runs the requests which is not intentional) so it doesnt manage to write the rest of the body. Interesting it always around the 2mb area where it happens, 😕 but at least we can see where it gets the broken pipe from. So now we narrowed it down to nginx -> appsec. |
When running Immich (https://github.com/immich-app/immich) behind NPM(plus) and enabling Crowdsec/Appsec, it is not possible to upload files to the server via HTTP POST:
The issue was initially reported at ZoeyVid/NPMplus#1123.
The text was updated successfully, but these errors were encountered: