NGNIX proxy fails when downloading a large file

I have a Flask server that downloads files using chunks of 4096 bytes.
between the flask and the client, we use a Nginx server.
downloads fail after about more than 1 GB, with this error in the Ngnix proxy:

024/01/07 15:03:45 [error] 23#23: *4891 readv() failed (104: Connection reset by 
peer) while reading upstream, client: *.*.*.*, server: , request: "GET /api/asset- 
service/v1/recordings/68f38d34-9e10-4bd1-a173-5b2217b70818/download? 
connector_uuid=f7e88796-4d87-4143-9c6c-54a8d154d9f6 HTTP/1.1", upstream: 
"http://*.*.*.*:8080/v1/api/recordings/68f38d34-9e10-4bd1-a173- 
5b2217b70818/download?connector_uuid=f7e88796-4d87-4143-9c6c-54a8d154d9f6", host: 
"*.*.*.*:8080", referrer: "https://localhost:8000/recordings"

I refactor the ngnix.conf file with all the solutions I found, but still getting the same error.

This is the ngnix conf:

load_module /usr/lib/nginx/modules/ndk_http_module.so;
load_module /usr/lib/nginx/modules/ngx_http_lua_module.so;

pcre_jit on;

worker_processes  1;
events {
    worker_connections  1024;
}

env STACK_NAME;
env NAMESPACE;
http {
    server_tokens off;
    client_body_timeout 3600;
    gzip on;
    gzip_static on;
    gzip_min_length  500;
    gzip_proxied     any;
    gzip_comp_level 4;
    gzip_types  text/css text/javascript text/xml text/plain text/x-component application/javascript application/json application/xml application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
    gzip_vary on;
    gzip_disable     "msie6";
    resolver kube-dns.kube-system.svc.cluster.local ipv6=off;

    # Increased timeouts for large file transfers
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
    proxy_connect_timeout 3600s;

    # Buffer size adjustments
    proxy_buffer_size  128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
    types_hash_max_size 4096;
    # Keepalive connections
    keepalive_timeout  300s;
    keepalive_requests 10000;
    # resolver 127.0.0.11 ipv6=off;
    client_max_body_size       0;
    proxy_max_temp_file_size   0;
    proxy_buffering off;
    server_names_hash_bucket_size 256;
    log_format trace '$remote_addr $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ($request_id)';


    server {
        set_by_lua $kn 'return os.getenv("NAMESPACE")' ;
        listen       443 ssl;
        listen      8080 ssl;

        # redirect http to https
        error_page 497 https://$host:$server_port$request_uri;

        ssl_protocols  TLSv1.2 TLSv1.3;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;

        access_log /var/log/nginx/access.log trace;

    
        add_header X-Frame-Options “DENY”; #Prevent ClickJacking
        add_header X-XSS-Protection "1; mode=block"; #XSS Filter
        add_header X-Content-Type-Options nosniff; #Prevent Mime-Type Risks
    

        location /ws {

            location ~ /ws/socket.io/(.*) {

                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_pass http://notifications-service.$kn.svc.cluster.local:8080/socket.io/$1$is_args$args;
            }

            location ~ ^/ws/wsproxy-service/(.*) {
                proxy_read_timeout 3600s;
                proxy_send_timeout 3600s;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Request-ID $request_id;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_pass http://wsproxy-service.$kn.svc.cluster.local:8080/api/$1$is_args$args;
            }
        }

        location /api {
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            location ~ ^/api/([w-]*)/v(d+)/swagger.json {

                proxy_pass http://$1.$kn.svc.cluster.local:8080/v$2/swagger.json;
            }

            location ~ ^/api/([w-]*)/v(d+)/ui {

                proxy_pass http://$1.$kn.svc.cluster.local:8080/v$2/ui;
            }

            location ~* ^/api/([w-]*)/v(d+)/(.*) {
                # Adjusted timeouts for large file transfers
                proxy_read_timeout 3600s;
                proxy_send_timeout 3600s;
                if ($request_method = OPTIONS ) {
                    add_header Access-Control-Allow-Origin *;
                    add_header Access-Control-Allow-Methods "GET, OPTIONS, PUT, DELETE";
                    add_header Access-Control-Allow-Headers "origin, authorization, accept, access-code, aad-token, Content-type";
                    add_header Access-Control-Allow-Credentials "true";
                    add_header Content-Length 0;
                    add_header Content-Type text/plain;
                    return 200;
                }

                rewrite_by_lua '
                    if string.match(ngx.var.request_uri, "/health$") == nil
                    and string.match(ngx.var.request_uri, "/beat_health$") == nil
                    and string.match(ngx.var.request_uri, "/celery_health/.*") == nil
                    and string.match(ngx.var.request_uri, "/admin/create_db$") == nil
                    and ngx.var.request_uri ~= "/api/user-service/v1/decrypt-token" then
                        local res = ngx.location.capture("/check_license_expiration")
                        if (res) and res.status ~= 200 then
                            ngx.exit(ngx.HTTP_PAYMENT_REQUIRED)
                        end
                    end
                ';

                proxy_http_version 1.1;
                proxy_set_header HOST $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Request-ID $request_id;
                proxy_send_timeout         1200;
                proxy_read_timeout         1200;

                proxy_pass http://$1.$kn.svc.cluster.local:8080/v$2/api/$3$is_args$args;
            }
        }

        location /tests {
            location ~* ^/tests/([w-]*)/(.*) {
                proxy_http_version 1.1;
                proxy_set_header HOST $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Request-ID $request_id;
                proxy_send_timeout         1200;
                proxy_read_timeout         1200;

                proxy_pass http://$1.$kn.svc.cluster.local:8080/tests/$2$is_args$args;
            }
        }

        location / {

            proxy_pass http://frontend.$kn.svc.cluster.local:8080;
        }

        location /nginx_status {
            stub_status;
            allow 127.0.0.1;
            deny all;
        }
    }
}

This is the client code (download_file function):

import { action, observable } from 'mobx';
import axios from 'axios';
import BaseStore from './baseStore';
import { getAuthHeaders } from '../utils/tokenRequest';
import MessageService from '../utils/MessageService';

class RecordingsStore extends BaseStore {
    @observable downloadingFiles = new Map();

    downloadBlob(blob, originalFilename) {
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = originalFilename;

      // Append to html link element page
      document.body.appendChild(link);

      // Start download
      link.click();

      setTimeout(() => {
        // Clean up and remove the link
        link.parentNode.removeChild(link);
        window.URL.revokeObjectURL(url);
      }, 100);
    }

    @action
    async downloadFile(recording, messages, i18next) {
      try {
        const cancelToken = axios.CancelToken.source();
        this.downloadingFiles.set(recording.id, { progress: '0', cancelToken });
        const authHeaders = await getAuthHeaders();
        const headers = {
          ...authHeaders,
        };
        const response = await axios.get(`api/asset-service/v1/recordings/${recording.id}/download?connector_uuid=${recording.connector_uuid}`, {
          headers,
          withCredentials: true,
          responseType: 'blob',
          onDownloadProgress: (progressEvent) => {
            const percentage = ((progressEvent.loaded * 100) / progressEvent.total).toFixed(1);
            this.downloadingFiles.set(recording.id, { progress: percentage, cancelToken });
          },
          cancelToken: cancelToken.token,
        });
        const contentDisposition = response.headers.get('content-disposition');
        const filenameMatch = contentDisposition && contentDisposition.match(/filename="?([^";]+)"?/);
        const originalFilename = filenameMatch ? filenameMatch[1] : 'unknown_filename';

        this.downloadBlob(response.data, originalFilename);
      } catch (error) {
        if (!axios.isCancel(error)) {
          console.error('failed to download file', error);
          MessageService.showMessage(messages, error?.response?.status || 500, {}, i18next);
        }
      } finally {
        this.downloadingFiles.delete(recording.id);
      }
    }

    @action
    cancelDownload(id) {
      const downloadingFile = this.downloadingFiles.get(id);
      if (downloadingFile) {
        downloadingFile.cancelToken.cancel();
      }
    }
}

export default new RecordingsStore();

Thanks