Evolution API Redis Disconnect & Iptables Errors on YunoHost/Docker Setup

Describe the problem/error/question

Environment:

  • OS: Debian 12 (via YunoHost)

  • Setup: Evolution API running on Docker alongside YunoHost services (n8n, etc.)

  • Infrastructure: Self-hosted on a VPS

The Issue: I’m running Evolution API via Docker Compose. Despite having a Redis service defined in my docker-compose.yml, the API logs are flooded with: [Redis] redis disconnected

Furthermore, when I try to restart the stack with docker compose up -d, I occasionally hit this networking error: Failed to Setup IP tables: Unable to enable ACCEPT OUTGOING rule: (iptables: No chain/target/match by that name)

My Current docker-compose.yml Snippet:

  evolution_api:
    image: atendai/evolution-api:latest
    environment:
      - CACHE_REDIS_ENABLED=true
      - CACHE_REDIS_HOST=redis
      - CACHE_REDIS_PORT=6379
    depends_on:
      - redis

  redis:
    image: redis:7-alpine

What I’ve Tried:

  1. Changing CACHE_REDIS_HOST to redis://redis:6379.

  2. Running yunohost firewall reload.

  3. Attempting to bypass the YunoHost SSO for n8n by setting it to ‘Visitor’ access.

Questions:

  1. Is YunoHost’s native Redis service or its iptables management (AFW) known to conflict with Docker’s internal networking?

  2. How can I ensure the Docker container bypasses YunoHost’s firewall rules to maintain a stable connection to its own Redis container?

  3. Are there specific DOCKER-USER chain rules I should manually inject to stop the ACCEPT OUTGOING failures?

What is the error message (if any)?

Information on your n8n setup

  • n8n version: 2.15.1
  • Database (default: SQLite): default
  • n8n EXECUTIONS_PROCESS setting (default: own, main): default
  • Running n8n via (Docker, npm, n8n cloud, desktop app): systemd service (YunoHost)
  • Operating system: Debian 12

See if below helps.

This is most likely a classic conflict between Docker’s networking engine and YunoHost’s firewall (AFW) on Debian 12.

The root cause is that YunoHost manages the firewall using nftables (and previously iptables), and when it reloads or applies rules, it often flushes the iptables chains. Docker creates its own custom chains (like the DOCKER chain) to handle container routing. When YunoHost flushes these, Docker tries to add rules to a chain that no longer exists, resulting in the error: iptables: No chain/target/match by that name.

Because the networking rules are broken, your evolution_api container cannot “see” the redis container, even though they are in the same compose file. This leads to the redis disconnected flood.

Here is the step-by-step solution to fix both issues.

1. Fix the Configuration (Evolution API)

The Evolution API expects a Connection URI, not separate Host and Port variables. You are using CACHE_REDIS_HOST, which the API likely ignores in favor of CACHE_REDIS_URI.

Update your docker-compose.yml environment section: Remove CACHE_REDIS_HOST and CACHE_REDIS_PORT and replace them with CACHE_REDIS_URI.

# Change this:
- CACHE_REDIS_ENABLED=true
- CACHE_REDIS_HOST=redis
- CACHE_REDIS_PORT=6379

# To this:
- CACHE_REDIS_ENABLED=true
- CACHE_REDIS_URI=redis://redis:6379

(Note: If you are using a password for Redis, the format is redis://:password@redis:6379).

2. Solve the iptables / YunoHost Conflict

To fix the Unable to enable ACCEPT OUTGOING rule error and restore connectivity between containers, you must ensure Docker re-creates its networking chains after YunoHost has initialized the firewall.

The Immediate Fix (Manual)

Run these commands in order to clear the conflict and force Docker to rebuild its rules:

# 1. Reload YunoHost firewall first
yunohost firewall reload

# 2. Restart the Docker daemon to force it to re-inject its chains into iptables
sudo systemctl restart docker

# 3. Bring your stack back up
docker compose up -d

The Permanent Fix (Automation)

Since YunoHost may reload the firewall during updates or via the WebUI, Docker’s rules will break again. To prevent this, you can create a simple systemd override to ensure Docker restarts whenever the firewall changes, or more simply, add a cron job/hook.

However, the most stable way on YunoHost is to ensure Docker is the last thing to start. If you find this happening frequently after reboots, run:

sudo systemctl enable docker

And if you manually reload the firewall, always follow it with sudo systemctl restart docker.

Answers to your specific questions:

1. Is YunoHost’s native Redis or iptables management known to conflict?

Yes. YunoHost’s firewall management is aggressive. It doesn’t “know” about Docker’s custom iptables chains. When YunoHost reloads its rules, it wipes the DOCKER chain. This is why you see the “No chain/target/match” error—Docker is trying to talk to a chain that YunoHost just deleted.

2. How can I ensure the Docker container bypasses YunoHost’s firewall?

Inter-container communication (Evolution API →→ Redis) happens on the Docker Bridge Network via the FORWARD chain. YunoHost’s firewall primarily manages the INPUT chain (traffic coming from the outside world). The containers don’t need to “bypass” the firewall; they just need the Docker-managed rules to exist. Restarting the Docker daemon after the firewall is active is the only way to restore those rules.

3. Are there specific DOCKER-USER chain rules I should inject?

No. The DOCKER-USER chain is for your custom rules (e.g., blocking a specific IP from hitting your API). The error you are seeing is not about a missing security rule, but a missing infrastructure chain. Injecting rules into DOCKER-USER won’t fix the ACCEPT OUTGOING failure because that failure happens in the core Docker setup process.

Hello,

Thank you for the answer.

I’ve tried your docker compose settings but I couldn’t succeeded. “Redis disconnected” error still contiunes. Here is my latest docker-compose.yml file:

version: '3.8'

services:
  evolution_api:
    image: atendai/evolution-api:latest
    container_name: evolution_api
    restart: always
    network_mode: "host"
    ports:
      - "8080:8080"
    environment:
      - SERVER_TYPE=http
      - SERVER_PORT=8080
      - SERVER_URL=http://my-server-ip:8080
      - CORS_ORIGIN=*
      - CORS_METHODS=GET,POST,PUT,DELETE,PATCH
      - AUTHENTICATION_TYPE=apikey
      - WA_PHONE_VERSION=2.3000.10125062854
      - CONFIG_SESSION_PHONE_CLIENT=Chrome
      - AUTHENTICATION_API_KEY=my-auth-api-key

      # Connecting to YunoHost database
      - DATABASE_ENABLED=true
      - DATABASE_PROVIDER=postgresql
      - DATABASE_CONNECTION_URI=postgresql://evolution:password@localhost:5432/evolution?schema=public

      # Connecting to YunoHost's Redis
      - CACHE_REDIS_ENABLED=true
      - CACHE_REDIS_URI=redis://redis:6379

Also, I have one more question do you think why QR code doesn’t appear? When I looked to the requests on my browser there nothing seems wrong. Everything seems 200 OK. Thank you.

The reason you are still seeing “Redis disconnected” is due to a networking mismatch in your new docker-compose.yml.

The Problem: network_mode: "host" vs. redis://redis

You have switched to network_mode: "host". In this mode, the container does not have its own internal Docker network; it shares the network of your VPS directly.

  • How it works now: Inside your container, localhost is the same as the VPS localhost.

  • The Error: You told the API to look for Redis at the hostname redis (redis://redis:6379). However, since you are not using a Docker bridge network, there is no DNS entry for “redis”. The container is looking for a machine named “redis” on your network and can’t find it.

Because you are trying to connect to YunoHost’s native Redis (which is running directly on the host OS), you must refer to it as localhost.

The Problem: network_mode: "host" vs. redis://redis

You have switched to network_mode: "host". In this mode, the container does not have its own internal Docker network; it shares the network of your VPS directly.

  • How it works now: Inside your container, localhost is the same as the VPS localhost.

  • The Error: You told the API to look for Redis at the hostname redis (redis://redis:6379). However, since you are not using a Docker bridge network, there is no DNS entry for “redis”. The container is looking for a machine named “redis” on your network and can’t find it.

Because you are trying to connect to YunoHost’s native Redis (which is running directly on the host OS), you must refer to it as localhost.

The Solution: Updated docker-compose.yml

Change your CACHE_REDIS_URI to use localhost.

services:
  evolution_api:
    image: atendai/evolution-api:latest
    container_name: evolution_api
    restart: always
    network_mode: "host" 
    # Note: 'ports' is ignored when using network_mode: host, 
    # the app will automatically bind to 8080 on your VPS IP.
    environment:
      - SERVER_TYPE=http
      - SERVER_PORT=8080
      - SERVER_URL=http://my-server-ip:8080
      - CORS_ORIGIN=*
      - CORS_METHODS=GET,POST,PUT,DELETE,PATCH
      - AUTHENTICATION_TYPE=apikey
      - WA_PHONE_VERSION=2.3000.10125062854
      - CONFIG_SESSION_PHONE_CLIENT=Chrome
      - AUTHENTICATION_API_KEY=my-auth-api-key

      # Connecting to YunoHost database (Correct)
      - DATABASE_ENABLED=true
      - DATABASE_PROVIDER=postgresql
      - DATABASE_CONNECTION_URI=postgresql://evolution:password@localhost:5432/evolution?schema=public

      # Connecting to YunoHost's Redis (FIXED)
      - CACHE_REDIS_ENABLED=true
      - CACHE_REDIS_URI=redis://localhost:6379 

Important Step: After saving the file, run:

docker compose up -d

Why the QR code isn’t appearing

You mentioned that the browser requests return 200 OK, but no QR code shows up. This is directly caused by the Redis disconnection.

Here is the technical reason:

  1. The Request (200 OK): When you ask for the QR code, the API server is running, so it accepts the request and returns a valid HTTP response. The “200 OK” just means “The server is alive and heard you.”

  2. The Process (Failure): To generate a QR code, Evolution API must initialize a WhatsApp session using the Baileys library. This library needs to store the session state and temporary connection data.

  3. The Crash: Evolution API uses Redis to manage this state. Because Redis is disconnected, the API fails to create the session in the background. It returns a success response to the browser, but the payload (the actual QR code data) is empty or invalid because the backend process crashed while trying to write to Redis.

Once you fix the CACHE_REDIS_URI to localhost and the “Redis disconnected” logs stop, the QR code will appear immediately.

Final Tip for YunoHost Users

If you still see “Redis disconnected” even after changing to localhost, it means YunoHost’s Redis is configured to only allow connections from specific users or has a password.

Check if YunoHost Redis has a password by running this on your VPS terminal:

redis-cli ping

  • If it returns PONG, it’s open.

  • If it returns (error) NOAUTH Authentication required, you must add the password to your URI: redis://:yourpassword@localhost:6379.*

Thank you for the answer.

I’ve actually solved both the Redis and the QR display issues.

Regarding the first issue with Redis, your solution worked for me. Making the changes you indicated in the compose file was enough, and I also restarted the YunoHost (AFW) firewall and Docker.

For the second issue, I found out that the Evolution API image is no longer supported due to old WhatsApp protocols. I switched the image and it worked immediately, without even needing to change my compose file. I’ve shared my settings below:

version: '3.8'

services:
  evolution_api:
    image: evoapicloud/evolution-api:latest # That's the stable one
    container_name: evolution_api
    restart: always
    network_mode: "host"

    environment:
      - SERVER_TYPE=http
      - SERVER_PORT=8080
      - SERVER_URL=http://your-server-ip:8080
      - CORS_ORIGIN=*
      - CORS_METHODS=GET,POST,PUT,DELETE,PATCH
      - AUTHENTICATION_TYPE=apikey
      - AUTHENTICATION_API_KEY=your-api-key
      # Mentioning seperately WhatsApp phone version and browser.
      - WA_PHONE_VERSION=2.3000.1030415680
      - CONFIG_SESSION_PHONE_CLIENT=Chrome

      # We're going to use YunoHost's database.
      - DATABASE_ENABLED=true
      - DATABASE_PROVIDER=postgresql
      - DATABASE_CONNECTION_URI=postgresql://evolution:password@localhost:5432/evolution?schema=public
      - CACHE_REDIS_ENABLED=true
      - CACHE_REDIS_URI=redis://localhost:6379

      # Optional: settings for extra stability.
      - DELAY_MESSAGE=1000
      - QR_CODE_EXPIRATION=600

    volumes:
      - ./evolution_instances:/evolution/instances

Even after solving those, there’s still one issue: I’ve set up the Evolution API trigger node, but when n8n receives a response, it gets stuck on “Loading data.” But, there’s nothing wrong when I’m executing normal nodes. It just occurs when I’m executing trigger node. I’ve already opened a GitHub issue for this, but I haven’t found any resources to fix it yet. Do you have any info on that? Thank you.

It is great to hear that the Redis and QR code issues are resolved! Switching to the evoapicloud image was the right move—the atendai images are indeed outdated and often fail with current WhatsApp Web protocols.

Regarding the n8n trigger node getting stuck on “Loading data,” this is a known pain point when running n8n and Evolution API on the same YunoHost server.

Since your normal nodes work, the “plumbing” (API ->-> n8n) is working for requests. However, a Trigger Node works in reverse: the API sends a Webhook to n8n. When n8n is in “Listen” mode and says “Loading data,” it is waiting for a valid HTTP request to hit its webhook endpoint.

Here are the three most likely reasons this is happening in your specific YunoHost setup:

1. The “Hairpin” Networking Issue (Most Likely)

You are likely using the Public URL of your n8n instance (e.g., https://n8n.yourdomain.com/webhook/``...) in the Evolution API webhook settings.

The Problem: When Evolution API (on the same server) tries to send data to your public URL, the request goes out to your VPS IP and then tries to come back in. Many firewalls (including YunoHost’s AFW/iptables) and some VPS providers block this “loopback” (Hairpin NAT) for security reasons. The request never actually reaches n8n, so the node stays on “Loading data” forever.

The Fix: In your Evolution API webhook configuration, try using the internal address of n8n instead of the public one.

  • Change: https://n8n.yourdomain.com/webhook/...

  • To: http://localhost:5678/webhook/... (or whatever port your n8n is running on internally).

2. n8n WEBHOOK_URL Environment Variable

If n8n doesn’t know its own public URL, it can sometimes generate “Test” webhook URLs that use localhost or an internal IP, which the Evolution API might not be able to route correctly depending on how the Docker network is interacting with the YunoHost systemd service.

The Fix: Ensure your n8n service (via YunoHost or environment variables) has the WEBHOOK_URL set explicitly:

WEBHOOK_URL=https://n8n.yourdomain.com/

If this isn’t set, n8n might be giving the API a URL that looks correct in the UI but is functionally broken for the incoming request.

3. Data Payload Mismatch (The “UI Hang”)

Since you switched to the evoapicloud image, the JSON structure of the events being sent to n8n might have changed slightly compared to what the n8n Evolution API node expects.

When n8n’s trigger node receives a request that it cannot parse into the expected schema, the UI sometimes hangs on “Loading data” instead of showing an error because it’s stuck in a loop trying to map the incoming JSON to the node’s internal fields.

How to test this:

  1. Create a standard Webhook Node in n8n (not the Evolution API trigger node).

  2. Copy that Webhook URL and put it into the Evolution API webhook settings.

  3. Trigger an event (send a message to the bot).

  4. If the standard Webhook node receives the data, then the issue is a schema mismatch in the Evolution API trigger node. In this case, you can actually build your entire workflow using the standard Webhook node and a “Set” or “Code” node to clean the data—this is often more stable than using the dedicated trigger node.

Summary Checklist for you:

  1. Test with a standard Webhook node. If this works, the problem is the Trigger Node’s code (Schema mismatch).

  2. Change the Webhook URL in Evolution API to http://localhost:5678/... to bypass the YunoHost firewall/loopback issue.

  3. Check n8n logs (sudo journalctl -u n8n or similar) while the node is “Loading data” to see if any 403 Forbidden or Connection Refused errors appear.

Magically, I solved the issue by updating n8n from version 1.15.1 to 1.19.2, though I don’t really understand how it was solved.