Dashboard 404 error using traefik.yml (works fine with same command line options)

I am running traefik 3.3.7 on docker swarm.
I am getting a 404 error accessing the traefik dashboard with the following traefik.yml config:

# traefik.yml

# Global settings
log:
  level: DEBUG

api:
  dashboard: true

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

# Providers
providers:
  swarm:
    exposedByDefault: false
    network: proxy
    watch: true

  file:
    directory: /etc/traefik/dynamic/
    watch: true

# Access Logs
accessLog:
  filePath: /var/log/traefik/access.log

The funny thing is, when I use the same config from command line, everything works great:

 command:
      - "--log.level=DEBUG"
      - "--api=true"
      - "--providers.swarm=true"
      - "--providers.swarm.exposedbydefault=false"
      - "--providers.docker.network=proxy"
      - "--providers.docker.watch=true"
      - "--accesslog=true"
      - "--accesslog.filepath=/var/log/traefik/access.log"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--providers.file.directory=/etc/traefik/dynamic/"
      - "--providers.file.watch=true"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https

Here is the log entry for static config using traefik.yml file:

025-07-09T14:18:19Z DBG github.com/traefik/traefik/v3/cmd/traefik/traefik.go:113 > Static configuration loaded [json] staticConfiguration={"accessLog":{"fields":{"defaultMode":"keep","headers":{"defaultMode":"drop"}},"filePath":"/var/log/traefik/access.log","filters":{},"format":"common"},"api":{"basePath":"/","dashboard":true},"entryPoints":{"web":{"address":":80","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576,"redirections":{"entryPoint":{"permanent":true,"priority":9223372036854775806,"scheme":"https","to":"websecure"}},"sanitizePath":true},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}},"websecure":{"address":":443","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576,"sanitizePath":true},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}}},"global":{"checkNewVersion":true},"log":{"format":"common","level":"DEBUG"},"providers":{"file":{"directory":"/etc/traefik/dynamic/","watch":true},"providersThrottleDuration":"2s","swarm":{"defaultRule":"Host({{ normalize .Name }})","endpoint":"unix:///var/run/docker.sock","network":"proxy","refreshSeconds":"15s","watch":true}},"serversTransport":{"maxIdleConnsPerHost":200},"tcpServersTransport":{"dialKeepAlive":"15s","dialTimeout":"30s"}}

Here is the log entry using command line:

2025-07-09T14:21:33Z DBG github.com/traefik/traefik/v3/cmd/traefik/traefik.go:113 > Static configuration loaded [json] staticConfiguration={"accessLog":{"fields":{"defaultMode":"keep","headers":{"defaultMode":"drop"}},"filePath":"/var/log/traefik/access.log","filters":{},"format":"common"},"api":{"basePath":"/","dashboard":true},"entryPoints":{"web":{"address":":80","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576,"sanitizePath":true},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}},"websecure":{"address":":443","forwardedHeaders":{},"http":{"maxHeaderBytes":1048576,"sanitizePath":true},"http2":{"maxConcurrentStreams":250},"transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s","readTimeout":"1m0s"}},"udp":{"timeout":"3s"}}},"global":{"checkNewVersion":true},"log":{"format":"common","level":"DEBUG"},"providers":{"docker":{"defaultRule":"Host({{ normalize .Name }})","endpoint":"unix:///var/run/docker.sock","exposedByDefault":true,"network":"proxy","watch":true},"providersThrottleDuration":"2s","swarm":{"defaultRule":"Host({{ normalize .Name }})","endpoint":"unix:///var/run/docker.sock","refreshSeconds":"15s","watch":true}},"serversTransport":{"maxIdleConnsPerHost":200},"tcpServersTransport":{"dialKeepAlive":"15s","dialTimeout":"30s"}}

Here are the labels on my traefik container:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.tls=true"
      - "traefik.http.routers.dashboard.rule=Host(`<redacted>`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.services.dashboard.loadbalancer.server.port=8080"

Thanks for any help you can give.

Share your full compose file, why all the bits and pieces?