Traefik falling back to self-signed certificate instead of requesting Let's Encrypt certificate

Hello together,

I have a strange issue where I just cannot seem to wrap my head around. I followed along with following tutorial to set up Traefik v3.6 in docker-compose: Setup Traefik Proxy in Docker Standalone - Traefik . But for some reason I just cannot get the Let’s Encrypt certificates to work.

Here’s my full docker-compose.yaml for setting up Traefik:

services:
  traefik:
    image: traefik:v3.6
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - "no-new-privileges=true"

    networks:
      - proxy

    ports:
      - "80:80"
      - "443:443"

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt

    command:
      # EntryPoints
      - "--entrypoints.web.address=:80"
      #- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      #- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      #- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.websecure.http.tls=true"

      # Explicitly disable TLS ALPN challenge (was suggested by ChatGPT, but did not help)
      - "--certificatesresolvers.le.acme.tlschallenge=false"

      # Letsencrypt TLS Configuration
      - "--certificatesresolvers.le.acme.email=domain@<mydomain>.at"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"

      # IMPORTANT: HTTP challenge has to be explicitly enabled in Traefik v3
      - "--certificatesresolvers.le.acme.httpchallenge=true"
      - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"

      # Make Letsencrypt default resolver for TLS-enabled routes
      - "--entrypoints.websecure.http.tls.certresolver=le"

      # Providers
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=proxy"

      # API + Dashboard
      - "--api.dashboard=true"
      - "--api.insecure=false"

      # Observability
      - "--log.level=INFO"
      - "--accesslog=true"
      - "--metrics.prometheus=true"

    labels:
      # Enable self-routing
      - "traefik.enable=true"

      # Dashboard router
      - "traefik.http.routers.dashboard.rule=Host(`proxy.<mydomain>.at`)"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.tls=true"

      # Basic-auth middleware
      - "traefik.http.middlewares.dashboard-auth.basicauth.users=<secret>"
      - "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker"

networks:
  proxy:
    name: proxy
    external: true

volumes:
  letsencrypt:

Initially, I had the entrypoint redirections from HTTP to HTTPS also set up, but I commented them out since I was unsure if this might cause any weird issues with the ACME HTTP challenge.

Traefik will just always fall back to the default self-signed Traefik certificate when opening the Traefik dashboard on “proxy.mydomain.at”:

Here are the logs from my Docker container:

2025-11-27T09:45:37Z INF Traefik version 3.6.2 built on 2025-11-18T16:12:58Z version=3.6.2
2025-11-27T09:45:37Z INF 
Stats collection is disabled.
Help us improve Traefik by turning this feature on :)
More details on: https://doc.traefik.io/traefik/contributing/data-collection/

2025-11-27T09:45:37Z INF Starting provider aggregator *aggregator.ProviderAggregator
2025-11-27T09:45:37Z INF Starting provider *traefik.Provider
2025-11-27T09:45:37Z INF Starting provider *acme.ChallengeTLSALPN
2025-11-27T09:45:37Z INF Starting provider *docker.Provider
2025-11-27T09:45:37Z INF Starting provider *acme.Provider
2025-11-27T09:45:37Z INF Testing certificate renew... acmeCA=https://acme-v02.api.letsencrypt.org/directory providerName=le.acme
root@de1:/home/slang/docker/traefik# docker logs traefik
2025-11-27T09:45:37Z INF Traefik version 3.6.2 built on 2025-11-18T16:12:58Z version=3.6.2
2025-11-27T09:45:37Z INF 
Stats collection is disabled.
Help us improve Traefik by turning this feature on :)
More details on: https://doc.traefik.io/traefik/contributing/data-collection/

2025-11-27T09:45:37Z INF Starting provider aggregator *aggregator.ProviderAggregator
2025-11-27T09:45:37Z INF Starting provider *traefik.Provider
2025-11-27T09:45:37Z INF Starting provider *acme.ChallengeTLSALPN
2025-11-27T09:45:37Z INF Starting provider *docker.Provider
2025-11-27T09:45:37Z INF Starting provider *acme.Provider
2025-11-27T09:45:37Z INF Testing certificate renew... acmeCA=https://acme-v02.api.letsencrypt.org/directory providerName=le.acme

Just for the sake of completeness, here is also my config for adventure-log which I want to host behind the Traefik reverse-proxy. Here, the same issue occurs with the self-signed certificate:

services:
  web:
    #build: ./frontend/
    image: ghcr.io/seanmorley15/adventurelog-frontend:latest
    container_name: adventurelog-frontend
    restart: unless-stopped
    env_file: .env
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.adventurelogweb.entrypoints=websecure"
      - "traefik.http.routers.adventurelogweb.rule=Host(`travel.<mydomain>.at`) && !(PathPrefix(`/media`) || PathPrefix(`/admin`) || PathPrefix(`/static`) || PathPrefix(`/accounts`))"
      - "traefik.http.routers.adventurelogweb.tls=true"
      - "traefik.http.routers.adventurelogweb.observability.metrics=true"
      - "traefik.http.routers.adventurelogweb.observability.accessLogs=true"
      - "traefik.http.routers.adventurelogweb.observability.tracing=true"
    depends_on:
      - server
    networks:
      - proxy

  db:
    image: postgis/postgis:16-3.5
    container_name: adventurelog-db
    restart: unless-stopped
    env_file: .env
    volumes:
      - postgres_data:/var/lib/postgresql/data/

  server:
    #build: ./backend/
    image: ghcr.io/seanmorley15/adventurelog-backend:latest
    container_name: adventurelog-backend
    restart: unless-stopped
    env_file: .env
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.adventurelogserver.entrypoints=websecure"
      - "traefik.http.routers.adventurelogserver.rule=Host(`travel.<mydomain>.at`) && (PathPrefix(`/media`) || PathPrefix(`/admin`) || PathPrefix(`/static`) || PathPrefix(`/accounts`))"
      - "traefik.http.routers.adventurelogserver.tls=true"
      - "traefik.http.routers.adventurelogserver.observability.metrics=true"
      - "traefik.http.routers.adventurelogserver.observability.accessLogs=true"
      - "traefik.http.routers.adventurelogserver.observability.tracing=true"
    depends_on:
      - db
    volumes:
      - adventurelog_media:/code/media/
    networks:
      - proxy

volumes:
  postgres_data:
  adventurelog_media:

networks:
  proxy:
    name: proxy
    external: true

If that is relevant: I am using Cloudflare for managing my domain name records and here is how I set up DNS for my server:
A server-ipv4-address de1.mydomain.at
AAAA server-ipv6-address de1.mydomain.at
CNAME travel de1.mydomain.at
CNAME proxy de1.mydomain.at

So basically, all subdomains point to de1.mydomain.at which then contains the IP address of my server. I wanted to do it like this so that I have to specify my IP addresses only once and can easily change them later.

I would highly appreciate any help, since I am stuck on this issue for a few hours already and I just cannot figure it out.

Try to remove this line, it might overwrite the certResolver assignment to entrypoint.

      - "traefik.http.routers.dashboard.tls=true"

It enough to enable TLS on entrypoint.

Oh wow, that was a lot simpler than expected. I tried it out and this seems to be the missing puzzle piece. After removing this line, everything is working perfectly fine and Traefik correctly requests a new certificate via letsencrypt and serves that.

Thanks a lot for the quick and admittedly easy fix. Appreciate your time!

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.