Workflow Connection Lost

I have an issue which my workflow menu or page has “Connection Lost” (as picture below), that resulting I can’t import my workflow file. However the instance is not showing any error on the log:

2025-08-07T07:40:15.085Z | debug | Querying database for waiting executions {"scopes":["waiting-executions"],"file":"wait-tracker.js","function":"getWaitingExecutions"}
2025-08-07T07:41:15.087Z | debug | Querying database for waiting executions {"scopes":["waiting-executions"],"file":"wait-tracker.js","function":"getWaitingExecutions"}
2025-08-07T07:42:15.087Z | debug | Querying database for waiting executions {"scopes":["waiting-executions"],"file":"wait-tracker.js","function":"getWaitingExecutions"}
2025-08-07T07:43:15.088Z | debug | Querying database for waiting executions {"scopes":["waiting-executions"],"file":"wait-tracker.js","function":"getWaitingExecutions"}
2025-08-07T07:44:15.089Z | debug | Querying database for waiting executions {"scopes":["waiting-executions"],"file":"wait-tracker.js","function":"getWaitingExecutions"}
2025-08-07T07:45:15.090Z | debug | Querying database for waiting executions {"scopes":["waiting-executions"],"file":"wait-tracker.js","function":"getWaitingExecutions"}

The error actually showing up on the browser console , which it can’t connect to the WebSocket Client as follows:

Here are my environment variables configuration:

  • name: DB_TYPE
    value: “postgresdb”
  • name: DB_POSTGRESDB_DATABASE
    value: “test”
  • name: DB_POSTGRESDB_HOST
    value: “test”
  • name: DB_POSTGRESDB_PORT
    value: “5432”
  • name: DB_POSTGRESDB_USER
    value: “test”
  • name: DB_POSTGRESDB_PASSWORD
    value: “x”
  • name: GENERIC_TIMEZONE
    value: “Asia/Jakarta”
  • name: “N8N_HOST”
    value: “test.domain..co.id”
  • name: “N8N_PORT”
    value: “5678”
  • name: “WEBHOOK_URL”
    value: “https://test.domain.co.id/n8n-dsd/
  • name: “N8N_PATH”
    value: “/n8n-dsd”
  • name: N8N_LOG_LEVEL
    value: “debug”
  • name: QUEUE_HEALTH_CHECK_ACTIVE
    value: “true”
  • name: N8N_COMMUNITY_PACKAGES_ENABLED
    value: “false”

Information on your n8n setup

  • **n8n version: 1.105.2
  • Database (default: SQLite): PostgreSQL
  • n8n EXECUTIONS_PROCESS setting (default: own, main): own
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker
  • Operating system: 3.23 Alpine

Hi there, does this happen after lets say you update your n8n? or you just change some env variable or it just error randomly?

if it is just error randomly, it might be just a one time thing and just giving it some time maybe will fix it

No I did not update anything nor change some env variable, the error happened when I deploy the n8n to the Kubernetes.

I also want to confirm, does n8n need an internet connection to access the workflow ? Because it is working on my local.

I have tried to re-deploy the n8n the issue still occur

Your reverse proxy is most likely not accepting websockets. Have you enabled websocketsupport?

so the connection lost is caused by the n8n service can’t connect to the websockets ?

Hi if your reverse proxy doent support websocket you can change your env to use sse intead websocket

N8N_PUSH_BACKEND = sse

you can review all your env from this docs Deployment environment variables | n8n Docs

so you are saying that my n8n services need a websocket connection to resolve the connection lost ?

yes your log error show like that, you can try change my recommendation and see if it resolve your issue.

Okay, I have used your suggested configuration, it seems the websocket error has gone, however I am still getting connection lost on the workflow, can’t import workflow file

Can you give more detail, which reverse proxy are you using? its already connect to your domain or its localhost?

I use the NGINX Ingress Controller on the Kubernetes.
And yes, its already connected to my host domain

  proxy_pass http://n8n-main:5678;
  proxy_set_header Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Real-Port $remote_port;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header REMOTE-HOST $remote_addr;
  proxy_connect_timeout 60s;
  proxy_send_timeout 600s;
  proxy_read_timeout 600s;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";

Thats my default config for nginx so i can using websocket support on n8n env

I have tried not using the
N8N_PUSH_BACKEND = sse

And try your configuration, the error websocket and the connection lost still persists

2025-08-08T04:11:24.599Z [Rudder] debug: no existing flush timer, creating new one
2025-08-08T04:11:32.370Z | debug | Querying database for waiting executions {"scopes":["waiting-executions"],"file":"wait-tracker.js","function":"getWaitingExecutions"}
2025-08-08T04:11:34.601Z [Rudder] debug: in flush
2025-08-08T04:11:34.601Z [Rudder] debug: cancelling existing flushTimer...
2025-08-08T04:11:37.098Z [Rudder] debug: no existing flush timer, creating new one
2025-08-08T04:11:47.099Z [Rudder] debug: in flush
2025-08-08T04:11:47.099Z [Rudder] debug: cancelling existing flushTimer...
Error fetching feature flags Error [PostHogFetchNetworkError]: Network error while fetching PostHog
    at new PostHogFetchNetworkError (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/posthog-node@3.2.1/node_modules/posthog-core/src/index.ts:41:5)
    at PostHog.<anonymous> (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/posthog-node@3.2.1/node_modules/posthog-core/src/index.ts:546:17)
    at step (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/posthog-node@3.2.1/node_modules/node_modules/tslib/tslib.es6.js:102:23)
    at Object.throw (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/posthog-node@3.2.1/node_modules/node_modules/tslib/tslib.es6.js:83:53)
    at rejected (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/posthog-node@3.2.1/node_modules/node_modules/tslib/tslib.es6.js:74:65) {
  error: DOMException [TimeoutError]: The operation was aborted due to timeout
      at node:internal/deps/undici/undici:13510:13,
  [cause]: DOMException [TimeoutError]: The operation was aborted due to timeout
      at node:internal/deps/undici/undici:13510:13
}
ValidationError: The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users. See https://express-rate-limit.github.io/ERR_ERL_UNEXPECTED_X_FORWARDED_FOR/ for more information.
    at Object.xForwardedForHeader (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/express-rate-limit@7.5.0_express@5.1.0/node_modules/express-rate-limit/dist/index.cjs:187:13)
    at Object.wrappedValidations.<computed> [as xForwardedForHeader] (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/express-rate-limit@7.5.0_express@5.1.0/node_modules/express-rate-limit/dist/index.cjs:398:22)
    at Object.keyGenerator (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/express-rate-limit@7.5.0_express@5.1.0/node_modules/express-rate-limit/dist/index.cjs:671:20)
    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/express-rate-limit@7.5.0_express@5.1.0/node_modules/express-rate-limit/dist/index.cjs:724:32
    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/express-rate-limit@7.5.0_express@5.1.0/node_modules/express-rate-limit/dist/index.cjs:704:5 {
  code: 'ERR_ERL_UNEXPECTED_X_FORWARDED_FOR',
  help: 'https://express-rate-limit.github.io/ERR_ERL_UNEXPECTED_X_FORWARDED_FOR/'
}

Its about your kubernetes config and i guess you must be using n8n queue mode on there and it must be config separately.

image

the easiest way to resolve your issue is try to use helm from this n8n 0.23.0 · riatlas/n8n its helps to learn how to setup n8n on kubernetes cluster or you can try with minim setup with docker compose to figure out all config and env on n8n then customize your needs with kubernetes

# Default values for n8n-service.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
replicaCount: 1

# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
image:
  repository: own-hosted-registyr.co..id/dev/n8n
  # This sets the pull policy for images.
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "latest"

# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets:
  - name: my-secret
# This is to override the chart name.
nameOverride: ""
fullnameOverride: ""

# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/
serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # Automatically mount a ServiceAccount's API credentials?
  automount: true
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""

# This is for setting Kubernetes Annotations to a Pod.
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
podAnnotations: {}
# This is for setting Kubernetes Labels to a Pod.
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
podLabels: {}

podSecurityContext: {}
  # fsGroup: 2000

securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000

# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/
service:
  # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
  type: NodePort
  # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports
  port: 80
  targetPort: 5678
  nodePort: 31242

# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
ingress:
  enabled: true
  className: ""
  annotations:
    kubernetes.io/ingress.class: nginx-intranet
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/server-snippets: |
      location / {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
      }

  hosts:
    - host: example.own.domain.co.id
      paths:
        - path: /n8n(/|$)(.*)
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

env:
  - name: DB_TYPE
    value: "postgresdb"
  - name: DB_POSTGRESDB_DATABASE
    value: "postgres"
  - name: DB_POSTGRESDB_HOST
    value: "IP"
  - name: DB_POSTGRESDB_PORT
    value: "5432"
  - name: DB_POSTGRESDB_USER
    value: "example"
  - name: DB_POSTGRESDB_PASSWORD
    value: "example"
  - name: GENERIC_TIMEZONE
    value: "Asia/Jakarta"
  - name: N8N_HOST
    value: "example.own.domain.co.id"
  - name: N8N_PORT
    value: "5678"
  - name: N8N_PATH
    value: "/n8n/"
  - name: N8N_LOG_LEVEL	
    value: "debug"  
  - name: N8N_COMMUNITY_PACKAGES_ENABLED 
    value: "false"
    

resources:
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 200m
    memory: 256Mi

# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
livenessProbe:
  httpGet:
    path: /
    port: http
readinessProbe:
  httpGet:
    path: /
    port: http

# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

# Additional volumes on the output Deployment definition.
volumes: []
# - name: foo
#   secret:
#     secretName: mysecret
#     optional: false

# Additional volumeMounts on the output Deployment definition.
volumeMounts: []
# - name: foo
#   mountPath: "/etc/foo"
#   readOnly: true

nodeSelector: {}

tolerations: []

affinity: {}

I have the simillar helm configuration as follow

is it working?

unfortunately no, the connection lost still exists

I found the solution below:

https://k8s.co.il/kubernetes/troubleshooting-n8n-websocket-issues-on-nginx-ingress/


Ingress yaml :

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    ...
    nginx.org/proxy-read-timeout: '3600'
    nginx.org/proxy-send-timeout: '3600'
    nginx.org/websocket-services: n8n  #your n8n service-name

Good luck!

No luck, still got connection lost:

{{- if .Values.ingress.enabled -}}
{{- $fullName := include "n8n-service.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
  {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
  {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
  {{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
  name: {{ $fullName }}
  labels:
    {{- include "n8n-service.labels" . | nindent 4 }}
  {{- with .Values.ingress.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
spec:
  {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
  ingressClassName: {{ .Values.ingress.className }}
  {{- end }}
  {{- if .Values.ingress.tls }}
  tls:
    {{- range .Values.ingress.tls }}
    - hosts:
        {{- range .hosts }}
        - {{ . | quote }}
        {{- end }}
      secretName: {{ .secretName }}
    {{- end }}
  {{- end }}
  rules:
    {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
          {{- range .paths }}
          - path: {{ .path }}
            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
            pathType: {{ .pathType }}
            {{- end }}
            backend:
              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
              service:
                name: {{ $fullName }}
                port:
                  number: {{ $svcPort }}
              {{- else }}
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
              {{- end }}
          {{- end }}
    {{- end }}
{{- end }}
ingress:
  enabled: true
  className: ""
  annotations:
    kubernetes.io/ingress.class: nginx-intranet
    nginx.org/proxy-read-timeout: "3600"
    nginx.org/proxy-send-timeout: "3600"
    nginx.org/rewrite-target: /$1
    nginx.org/use-regex: "true"
    nginx.org/websocket-services: n8n
    nginx.org/server-snippets: |
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "Upgrade";
  hosts:
    - host: domain.example.co.id
      paths:
        - path: /(.*)
          pathType: ImplementationSpecific