Unable to Get SSL Certificate for WSS with Traefik – acme.json Remains Empty

I'm trying to use Traefik as a reverse proxy for a WebSocket Secure (WSS) connection and forward the messages to a local server running on port 9001. However, I’ve encountered an issue where the acme.json file remains empty, and the expected SSL certificate is not being generated for my domain.

Here is the general setup:

Docker compose
I’m running Traefik in a Docker container, and the following is my basic configuration:

services:
  proxy:
    image: traefik:v3.3
    container_name: traefik
    restart: unless-stopped
    labels:
      - traefik.enable=true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./traefik.yml:/traefik.yml
      - /var/run/docker.sock:/var/run/docker.sock
      - ./Logs/traefik:/logs/
      - ./letsencrypt:/letsencrypt

Traefik Configuration (traefik.yml):

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: "websecure"
          scheme: "https"
  websecure:
    address: ":443"

certificatesResolvers:
  letsencrypt:
    acme:
      email: "your-email@example.com"
      storage: "/letsencrypt/acme.json"
      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      tlsChallenge: {}

http:
  routers:
    softphone:
      rule: "Host(`<URL>`)"
      service: softphoneServer
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt

  services:
    softphoneServer:
      loadBalancer:
        servers:
          - url: "http://10.4.0.5:9001"

log:
  level: DEBUG
  filePath: logs/traefik.log
accessLog:
  filePath: "/logs/access.log"

Problem:

Despite correctly configuring the certificates resolver with ACME and setting up the necessary entry points, the acme.json file remains empty. I’ve confirmed the file has the correct permissions and is writable by the Traefik container. I’ve also tried both the staging and production Let's Encrypt servers for testing purposes.

The acme.json file stays empty, and no SSL certificate is being generated.

What am I doing wrong?

Enable and check Traefik debug log (doc) and Traefik access log in JSON format (doc).

What is URL here?

It should just be a hostname, like sub.example.com, not a full URL.

The Traefik debug log:

2025-03-19T08:41:17Z INF github.com/traefik/traefik/v3/cmd/traefik/traefik.go:107 > Traefik version 3.3.4 built on 2025-02-25T10:11:01Z version=3.3.4
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/cmd/traefik/traefik.go:114 > Static configuration loaded [json] staticConfiguration={"accessLog":{"fields":{"defaultMode":"keep","headers":{"defaultMode":"drop"}},"filePath":"/logs/access.log","filters":{},"format":"json"},"certificatesResolvers":{"letsencrypt":{"acme":{"caServer":"https://acme-staging-v02.api.letsencrypt.org/directory","certificatesDuration":2160,"email":"<MY-EMAIL>","httpChallenge":{"entryPoint":"web"},"keyType":"RSA4096","storage":"/letsencrypt/acme.json","tlsChallenge":{}}}},"entryPoints":{"web":{"address":":80","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576,"redirections":{"entryPoint":{"permanent":true,"priority":9223372036854775806,"scheme":"https","to":"websecure"}}},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}},"websecure":{"address":":443","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}}},"global":{"checkNewVersion":true},"log":{"filePath":"logs/traefik.log","format":"common","level":"DEBUG"},"providers":{"providersThrottleDuration":"2s"},"serversTransport":{"maxIdleConnsPerHost":200},"tcpServersTransport":{"dialKeepAlive":"15s","dialTimeout":"30s"}}
2025-03-19T08:41:17Z INF github.com/traefik/traefik/v3/cmd/traefik/traefik.go:633 >
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-03-19T08:41:17Z INF github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:73 > Starting provider aggregator *aggregator.ProviderAggregator
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/pkg/server/server_entrypoint_tcp.go:231 > Starting TCP Server entryPointName=web
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/pkg/server/server_entrypoint_tcp.go:231 > Starting TCP Server entryPointName=websecure
2025-03-19T08:41:17Z INF github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:202 > Starting provider *traefik.Provider
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:203 > *traefik.Provider provider configuration config={}
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:227 > Configuration received config={"http":{"middlewares":{"redirect-web-to-websecure":{"redirectScheme":{"permanent":true,"port":"443","scheme":"https"}}},"routers":{"acme-http":{"entryPoints":["web"],"priority":9223372036854775807,"rule":"PathPrefix(`/.well-known/acme-challenge/`)","ruleSyntax":"v3","service":"acme-http@internal"},"web-to-websecure":{"entryPoints":["web"],"middlewares":["redirect-web-to-websecure"],"priority":9223372036854775806,"rule":"HostRegexp(`^.+$`)","ruleSyntax":"v3","service":"noop@internal"}},"serversTransports":{"default":{"maxIdleConnsPerHost":200}},"services":{"acme-http":{},"noop":{}}},"tcp":{"serversTransports":{"default":{"dialKeepAlive":"15s","dialTimeout":"30s"}}},"tls":{},"udp":{}} providerName=internal
2025-03-19T08:41:17Z INF github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:202 > Starting provider *acme.ChallengeTLSALPN
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:203 > *acme.ChallengeTLSALPN provider configuration config={}
2025-03-19T08:41:17Z INF github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:202 > Starting provider *acme.Provider
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/pkg/provider/aggregator/aggregator.go:203 > *acme.Provider provider configuration config={"HTTPChallengeProvider":{},"ResolverName":"letsencrypt","TLSChallengeProvider":{},"caServer":"https://acme-staging-v02.api.letsencrypt.org/directory","certificatesDuration":2160,"email":"<MY-EMAIL>","httpChallenge":{"entryPoint":"web"},"keyType":"RSA4096","storage":"/letsencrypt/acme.json","store":{},"tlsChallenge":{}}
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:232 > Attempt to renew certificates "720h0m0s" before expiry and check every "24h0m0s" acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory providerName=letsencrypt.acme
2025-03-19T08:41:17Z INF github.com/traefik/traefik/v3/pkg/provider/acme/provider.go:884 > Testing certificate renew... acmeCA=https://acme-staging-v02.api.letsencrypt.org/directory providerName=letsencrypt.acme
2025-03-19T08:41:17Z DBG github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:227 > Configuration received config={"http":{},"tcp":{},"tls":{},"udp":{}} providerName=letsencrypt.acme
2025-03-19T08:41:18Z DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:321 > No default certificate, fallback to the internal generated certificate tlsStoreName=default
2025-03-19T08:41:18Z DBG github.com/traefik/traefik/v3/pkg/middlewares/redirect/redirect_scheme.go:29 > Creating middleware entryPointName=web middlewareName=redirect-web-to-websecure@internal middlewareType=RedirectScheme routerName=web-to-websecure@internal
2025-03-19T08:41:18Z DBG github.com/traefik/traefik/v3/pkg/middlewares/redirect/redirect_scheme.go:30 > Setting up redirection to https 443 entryPointName=web middlewareName=redirect-web-to-websecure@internal middlewareType=RedirectScheme routerName=web-to-websecure@internal
2025-03-19T08:41:18Z DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=web middlewareName=traefik-internal-recovery middlewareType=Recovery
2025-03-19T08:41:18Z DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:321 > No default certificate, fallback to the internal generated certificate tlsStoreName=default
2025-03-19T08:41:18Z DBG github.com/traefik/traefik/v3/pkg/middlewares/redirect/redirect_scheme.go:29 > Creating middleware entryPointName=web middlewareName=redirect-web-to-websecure@internal middlewareType=RedirectScheme routerName=web-to-websecure@internal
2025-03-19T08:41:18Z DBG github.com/traefik/traefik/v3/pkg/middlewares/redirect/redirect_scheme.go:30 > Setting up redirection to https 443 entryPointName=web middlewareName=redirect-web-to-websecure@internal middlewareType=RedirectScheme routerName=web-to-websecure@internal
2025-03-19T08:41:18Z DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=web middlewareName=traefik-internal-recovery middlewareType=Recovery

The access log is empty on startup.

I was mistaken with this contains just the hostname, as you mentioned.

Your domain and Traefik is reachable from Internet?

Try a request to see if it shows up in debug or access log.