Webhooks getting 400 Error with Project VPS, Caddy and Cloudflare

1. The problem I’m having:

I have a Node.js application using LemonSqueezy webhooks that works perfectly in local environment and other hosting providers like fly.io. However, when deployed on my VPS using Caddy as reverse proxy with Cloudflare, the webhooks fail with a signature verification error. The error persists even when Cloudflare is paused, suggesting an issue with how the request body is being handled through Caddy. Error: ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH occurs during webhook signature verification.

I don’t exactly know if this is a Caddy problem or not but weirdly enough even after extensive logging in my code none of them show up in my docker logs, and that is why i am here asking for your help.

I will be honest and say that this is my first time hosting a full web app on a VPS with Caddy and Cloudflare especially a one with payment integration so if i have made any mistake please be kind and help me through it, also ignore any minor issues in my post as this is my first time posting in the community here.

2. Error messages and/or full log output:

text

Webhook error: RangeError: Input buffers must have the same byte length
    at _paymentsWebhookfn (/app/src/payment/lemonSqueezy/webhook.ts:27:17)
    at <anonymous> (/app/build/server/src/routes/apis/index.ts:39:14)
    at <anonymous> (/app/out/sdk/server/utils.ts:26:11)
    at Layer.handle [as handle_request] (/app/build/server/node_modules/express/lib/router/layer.js:95:5)
    at next (/app/build/server/node_modules/express/lib/router/route.js:149:13)
    at /app/build/server/node_modules/body-parser/lib/read.js:137:5

3. Caddy version:

bash

Caddy v2.7.6

4. How I installed and ran Caddy:

a. System environment:

  • Ubuntu 22.04 LTS
  • Docker for containerization
  • Caddy as reverse proxy
  • Cloudflare for DNS and SSL

b. Command:

bash

docker run -d \
  --name myapp \
  --env-file .env.production \
  -p 127.0.0.1:3001:3001 \
  --network app-vps-network \
  myapp

c. Service/unit/compose file:

N/A - Using Docker directly

d. My complete Caddy config:

{
    auto_https off
}

myapp.com, www.myapp.com {
    encode gzip
    root * /home/username/webdevelopment/myapp/client
    try_files {path} /index.html
    file_server

    tls /home/username/webdevelopment/myapp/cloudflare-origin-cert.pem /home/username/webdevelopment/myapp/cloudflare-origin-key.pem

    log {
        output file /var/log/caddy/myapp_access.log
        format json
    }
}

api.myapp.com {
    @webhook {
        path /payments-webhook
        path /operations/*
    }

    handle @webhook {
        header Content-Type application/json
        header -Content-Encoding
        reverse_proxy localhost:3001 {
            header_up Host {http.request.host}
            header_up Content-Type application/json
            header_up X-Signature {http.request.header.X-Signature}
        }
    }
 handle {
        reverse_proxy localhost:3001
    }

    tls /home/username/webdevelopment/myapp/cloudflare-origin-cert.pem /home/username/webdevelopment/myapp/cloudflare-origin-key.pem

    log {
        output file /var/log/caddy/api_access.log
        format json
        level DEBUG
    }
}

bot.myapp.com {
    reverse_proxy localhost:3000

    tls /home/username/webdevelopment/myapp/cloudflare-origin-cert.pem /home/username/webdevelopment/myapp/cloudflare-origin-key.pem

    log {
        output file /var/log/caddy/bot_access.log
        format json
    }
}

5. Links to relevant resources:

Please use the latest version, v2.8.4.

You don’t need these, it’s redundant. Caddy already passes through headers as-is.

We don’t have any evidence of it being a Caddy problem. That log message doesn’t point to any specific issue in Caddy itself. You’ll need to debug your Node.js app to figure out why that happens (or ask the authors for help).