Traefik complains about STS and auth middleware conflicting.. but it's the same middleware

I am using Traefik 2.2 with the Docker and dynamic providers. I am new to Traefik, so I am guessing I have somehow screwed up my configuration, but for the life of me, I cannot understand what is causing this issue.

I am trying to add some headers for STS into some docker containers via header labels. The middleware is an on-the-fly created middleware using the docker service name. That works just fine. However, if I add in Basic Auth also, suddenly Traefik complains about the middlewares conflicting. I can do either the STS headers or the auth, and each works fine on its own, but I cannot use them both. I am confused because I thought they were part of the same middleware. Here's an example problematic docker-compose file:

version: "3.8"

services:

    whoami:
        image: containous/whoami
        restart: unless-stopped
        networks:
          - traefik_internal
        expose:
          - "80/tcp"
        labels:
          - "traefik.enable=true"
          - "traefik.http.services.whoami.loadbalancer.server.port=80"
          - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
          - "traefik.http.routers.whoami.entrypoints=https"
          - "traefik.http.routers.whoami.tls.certresolver=le"
          - "traefik.http.routers.whoami.middlewares=whoami"
          - "traefik.http.middlewares.whoami.headers.stsSeconds=31536000"
          - "traefik.http.middlewares.whoami.headers.stsIncludeSubdomains=true"
          - "traefik.http.middlewares.whoami.headers.stsPreload=true"
          - "traefik.http.middlewares.whoami.headers.forceSTSHeader=true"
          - "traefik.http.middlewares.whoami.basicauth.users=test:$$2y$$05$$43393mPT5a4.jZNTKYwYruATHG83KwAWI1HdwMAgbleoH1rI/6Hyu"

networks:
    traefik_internal:
        external:
            name: traefik_internal

That file will not work. I have to remove either the headers or the auth. If I have both, I get the following error from Traefik:

level=error msg="cannot create middleware: multi-types middleware not supported, consider declaring two different pieces of middleware instead" routerName=whoami@docker entryPointName=https

I have also tried making separate middleware in the dynamic provider which provides the STS headers, and simply declaring that the whoami service uses both middlewares, using something akin to this:

- "traefik.http.routers.whoami.middlewares=whoami,sts@file"
 - "traefik.http.middlewares.whoami.basicauth.users=test:$$2y$$05$$43393mPT5a4.jZNTKYwYruATHG83KwAWI1HdwMAgbleoH1rI/6Hyu"

But I got the same error.

I am hoping somebody can tell me what I have configured incorrectly, and why, and how to gain the ability to set headers as well as use basic auth in the same service.

Below is my config file:

defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
  [entryPoints.https]
  address = ":443"

[log]
  filePath = "/proc/self/fd/1"
  format = "common"
  level = "ERROR"

[acme]
  entryPoint = "https"
  OnHostRule = true

[Global]
  CheckNewVersion = false
  SendAnonymousUsage = true

[ServersTransport]
  InsecureSkipVerify = true

[providers.docker]
  watch = true
  endpoint = "unix:///var/run/docker.sock"
  exposedByDefault = false

[providers.file]
  watch = true
  filename = "/etc/traefik/dynamic.toml"

[certificatesResolvers.le.acme]
  email = "myemail@example.com"
  storage = "/letsencrypt/acme.json"
#  caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
  caServer = "https://acme-v02.api.letsencrypt.org/directory"
  [certificatesResolvers.le.acme.httpChallenge]
    entryPoint = "http"

And here is my dynamic provider file:

[http.routers]
  [http.routers.redirecttohttps]
    entryPoints = ["http"]
    middlewares = ["httpsredirect"]
    rule = "HostRegexp(`{host:.+}`)"
    service = "noop"

[http.services]
  [http.services.noop.loadBalancer]
    [[http.services.noop.loadBalancer.servers]]
      url = "http://0.0.0.0"

[http.middlewares]
  [http.middlewares.httpsredirect.redirectScheme]
    scheme = "https"

  [http.middlewares.server-header]
  [http.middlewares.auth]
  [http.middlewares.default.headers]

[tls.options]
  [tls.options.default]
     minVersion = "VersionTLS12"
     cipherSuites = [
       "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
       "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
       "TLS_AES_256_GCM_SHA384",
       "TLS_CHACHA20_POLY1305_SHA256"
      ]
     curvePreferences = [
       "CurveP521",
       "CurveP384"
      ]
     sniStrict = true

As you can see, I have some sections for headers and auth that I was initially trying to configure here, but eventually gave up. I have left them in here, since that's what's in my current file, but removing them did not change anything; I still got the above error.

I simply don't understand where the conflict is happening. From my view, I am creating this new "whoami" middleware on the fly when the docker service is started. Then I am assigning the various properties to that middleware, which include headers and auth. The middleware then adds those properties to the requests/responses, since it's "in the middle" between the router and the service. That makes logic sense to me. But is that not what's happening? Am I understanding it wrong?

You need a new name for your basicauth middleware, then append that to the middlewares for your router.

          - "traefik.http.routers.whoami.middlewares=whoami,myauth"
          ...
          - "traefik.http.middlewares.myauth.basicauth.users=test:$$2y$$05$$43393mPT5a4.jZNTKYwYruATHG83KwAWI1HdwMAgbleoH1rI/6Hyu"

Thank you for the quick and informative reply!

Can you tell me why it is necessary to create a new middleware? Is a middleware not able to have more than one component?

One middleware does one thing.

You can list them on the router as I showed in my previous post or if you have a group of middlewares that you want to reuse you can group them together using a Chain middleware.

Alternatively if you have a group you want to apply to all routes on an entrypoint you can define a default set of middlewares to apply.