Traefik & Pangolin Fixes

Traefik & Pangolin Fixes

From “unknown plugin type: badger” to ACME timeouts and rate limits—this guide gets you to green logs and valid TLS quickly.

Traefik 3.x Pangolin ACME/Let’s Encrypt Docker

What went wrong (anonymized)

We removed real domains/IPs. Examples below use example.com and RFC1918 ranges.

1) Badger plugin not loaded

Traefik tried to use a middleware before the plugin was declared and stored.

error="plugin: unknown plugin type: badger" … routerName=app-1@http
error="plugin: unknown plugin type: badger" … routerName=app-2@http
error="plugin: unknown plugin type: badger" … routerName=app-3@http

2) ACME validation failing (HTTP-01)

Multiple hostnames hit connection/timeout issues and triggered per-hostname rate limits.

Unable to obtain ACME certificate … rateLimited :: too many failed authorizations … host.example.com
… storage.example.com … console.example.com … nas.example.com

3) Private IP in certificate request

Including a LAN IP in a TLS router led ACME to reject the order.

Invalid identifiers requested :: Cannot issue for "192.168.0.50": IP address is in a reserved address block

4) Provider connectivity

Traefik couldn’t reach the Pangolin HTTP provider on pangolin:3001 due to networking.

Traefik & Pangolin Fixes

Need this implemented for you? Hire a vetted expert today.

Hire a Freelancer If you need live agent support, talk on the website chat.

Prerequisites

Networking

  • Public DNS A/AAAA records point to your proxy.
  • Ports 80/tcp and 443/tcp open from the internet.
  • Traefik and Pangolin on the same Docker network.

Files & Permissions

  • acme.json exists and is 0600.
  • Persistent volume for plugin storage (./plugins-storage).
  • Dynamic config mounted read-only.

Architecture (overview)

Internet → [80/443] → Traefik → (Routers/Middlewares) → Services
                                   └─ DNS API (DNS-01)
                                   └─ ACME (HTTP-01/.well-known)
      

Fast, reliable fixes

Enable the Badger plugin

Add the plugin to static config and persist plugin storage. Example snippets:

experimental:
  plugins:
    badger:
      moduleName: github.com/fosrl/badger
      version: v1.2.0

# docker-compose (add a volume)
volumes:
  - ./plugins-storage:/plugins-storage
environment:
  XDG_DATA_HOME: /plugins-storage

Pick one ACME method (and test safely)

  • HTTP-01: Ensure TCP/80 is open end-to-end and any CDN is “DNS only”.
  • DNS-01 (Cloudflare): Use dnsChallenge: provider: cloudflare with a token granting Zone:Read + DNS:Edit.
  • Use Staging CA while iterating to avoid rate limits.

Remove private IPs from TLS routers

Keep LAN access on plain HTTP (no TLS) or behind a trusted certificate, but never request ACME for RFC1918 IPs.

Network Traefik ↔ Pangolin

Put both containers on a shared Docker network (e.g., traefik_net) so http://pangolin:3001 resolves from Traefik.

Recommended file layout

Use a clean host path and relative volumes:

/opt/traefik/
├─ docker-compose.yml
├─ traefik/
│  ├─ traefik.yml
│  └─ dynamic_config.yml
└─ letsencrypt/
   └─ acme.json

Copy-ready dynamic config (safe defaults)

http:
  middlewares:
    redirect-to-https:
      redirectScheme:
        scheme: https

  routers:
    # HTTP → HTTPS for the public host only
    http-redirect:
      entryPoints: [web]
      rule: "Host(`host.example.com`)"
      middlewares: [redirect-to-https]
      service: noop@internal

    # Pangolin UI (HTTPS)
    pangolin-ui:
      entryPoints: [websecure]
      rule: "Host(`host.example.com`) && !PathPrefix(`/api/v1`)"
      service: next-service
      tls:
        certResolver: letsencrypt

    # Pangolin API (HTTPS)
    pangolin-api:
      entryPoints: [websecure]
      rule: "Host(`host.example.com`) && PathPrefix(`/api/v1`)"
      service: api-service
      tls:
        certResolver: letsencrypt

  services:
    next-service:
      loadBalancer: { servers: [ { url: "http://pangolin:3002" } ] }
    api-service:
      loadBalancer: { servers: [ { url: "http://pangolin:3000" } ] }

Extra: static config (snippet)

entryPoints:
  web: { address: ":80" }
  websecure: { address: ":443" }
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /letsencrypt/acme.json
      httpChallenge: { entryPoint: web }
api: { dashboard: true }
providers:
  file: { filename: /etc/traefik/dynamic.yml, watch: true }
  docker: { exposedByDefault: false }

Sanity checks before calling it done

No “unknown plugin type: badger”
ACME orders succeed (staging → prod)
Provider reachable at :3001

Troubleshooting quick hits

  • If HTTP-01 fails, curl the challenge path from the internet; any timeout means firewall/NAT/CDN.
  • If DNS-01 fails, check token scopes and Cloudflare zone.
  • If ACME rate-limits, pause and switch to staging until green.
  • Use docker exec traefik ls -l /plugins-storage to confirm plugin persistence.
  • Check docker network inspect to verify Traefik ↔ service connectivity.

Quick Checklist

  • Badger plugin declared in experimental.plugins
  • Plugins stored via ./plugins-storage + XDG_DATA_HOME
  • One ACME method configured (HTTP-01 or DNS-01)
  • No private IPs in any TLS router
  • Pangolin + Traefik on traefik_net
  • File provider watch: true for hot reloads

Useful Commands

docker network create traefik_net || true
docker network connect traefik_net traefik
docker network connect traefik_net pangolin
docker logs -n 200 traefik
curl -I http://host.example.com/.well-known/acme-challenge/test
Need a freelancer?

FAQ

How do I switch to DNS-01 safely?
Create a limited-scope API token (Zone Read + DNS Edit), set CF_API_TOKEN as an environment variable, and enable dnsChallenge. Test on Let’s Encrypt staging before production.
Why does ACME keep rate-limiting me?
Repeated failed challenges trigger limits. Fix routing/ports first, then request certificates using the staging CA. Once stable, switch to production.
Is the Badger plugin required?
No. It’s optional middleware. If unused, remove its references entirely to avoid unknown plugin type errors.
Can I terminate TLS at a CDN?
Yes, but ensure ACME validation still reaches Traefik. For HTTP-01, set proxy/CDN to pass through port 80 without caching or redirect loops.
How do I debug provider connectivity?
From the Traefik container: nc -vz pangolin 3001. If it fails, connect both containers to the same user-defined network.

Need implementation? Use the “Hire a Freelancer” button above, or talk to a live agent on the website chat.

© 2025 — Technical Guide. Traefik & Pangolin are respective trademarks of their owners.

About the author : Moreslot

About the author : Moreslot