### Do you want to request a *feature* or report a *bug*?
Bug
### What did y…ou do?
I startup Traefik in the exact same way multiple times in a CI environment, but I end up with different outcomes in Traefik's ACME server interaction using the [go-acme/lego](https://github.com/go-acme/lego) library.
### What did you expect to see?
I expected Traefik to use the ACME LEGO library to make _a single attempt_ to get a TLS certificate from the ACME server (one order), and then process it to succeed or fail.
### What did you see instead?
Instead I sometimes (25-75% of the times) see two almost simultaneously initiated orders with the ACME server when Traefik starts, and when this happens, a ACME server interaction failure can follow about 50% of the times.
### My analysis
I can spot when one or two ACME orders are placed by Traefik's use of the LEGO library against the ACME server by seeing either one or two lines of the following in the logs: __`acme: Obtaining bundled SAN certificate`__.
The logged line above comes from [here in go-acme/lego](https://github.com/go-acme/lego/blob/2da1ce06ea5a6454980e26d1226e2af4c659145f/certificate/certificates.go#L89-L97). When that happens, Traefik probably have invoked it twice, and __I suspect [this section](https://github.com/containous/traefik/blob/7928e6d0cd4c7751a14bea5f74124f8a3cb829c0/pkg/provider/acme/provider.go#L320-L423) is ending up calling the [resolveCertifciate](https://github.com/containous/traefik/blob/7928e6d0cd4c7751a14bea5f74124f8a3cb829c0/pkg/provider/acme/provider.go#L425) function twice__, which in turn calls the go-acme/lego library's obtain function twice.
### Output of `traefik version`: (_What version of Traefik are you using?_)
```
Traefik version 2.2.1 built on 2020-04-29T18:02:09Z
```
### What is your environment & configuration (arguments, toml, provider, platform, ...)?
I've setup Pebble, Let's Encrypts ACME server meant for testing purposes, and start pebble first and await it to be ready, then start Traefik. This is done in separate VMs multiple times over as part of CI tests, and this is where I observe different outcomes between fully decoupled runs.
```yaml
# DYNAMIC CONFIGURATION
# dynamic.yaml: |
http:
middlewares:
hsts:
headers:
stsIncludeSubdomains: false
stsPreload: false
stsSeconds: 15724800
redirect:
redirectScheme:
permanent: true
scheme: https
scheme:
headers:
customRequestHeaders:
X-Scheme: https
routers:
default:
entrypoints:
- https
middlewares:
- hsts
- scheme
rule: PathPrefix(`/`)
service: default
tls:
certResolver: default
domains:
- main: local.jovyan.org
options: default
insecure:
entrypoints:
- http
middlewares:
- redirect
rule: PathPrefix(`/`)
service: default
services:
default:
loadBalancer:
servers:
- url: http://proxy-http:8000/
tls:
options:
default:
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
minVersion: VersionTLS12
sniStrict: true
# STATIC CONFIGURATION
# traefik.yaml: |
accessLog:
fields:
headers:
names:
Authorization: redacted
Cookie: redacted
Set-Cookie: redacted
X-Xsrftoken: redacted
filters:
statusCodes:
- 500-599
certificatesResolvers:
default:
acme:
caServer: https://pebble/dir
email: jovyan@jupyter.test
httpChallenge:
entryPoint: http
storage: /etc/acme/acme.json
entryPoints:
http:
address: :80
https:
address: :443
transport:
respondingTimeouts:
idleTimeout: 10m0s
log:
level: DEBUG
providers:
file:
filename: /etc/traefik/dynamic.yaml
```
### If applicable, please paste the log output in DEBUG level (`--log.level=DEBUG` switch)
I pasted the logs of an example of two orders being placed below as identified by two lines of `acme: Obtaining bundled SAN certificate`. But other examples are available in the links.
More are available:
- [one order (always (?) success with one order)](https://travis-ci.org/github/jupyterhub/zero-to-jupyterhub-k8s/jobs/693668494#L851)
- [two orders (success)](https://travis-ci.org/github/jupyterhub/zero-to-jupyterhub-k8s/jobs/693668495#L862-L863)
- [two orders (failure - lacking DEBUG level on logs)](https://travis-ci.org/github/jupyterhub/zero-to-jupyterhub-k8s/jobs/693624730#L806-L807)
```
Configuration loaded from file: /etc/traefik/traefik.yaml"
Traefik version 2.2.1 built on 2020-04-29T18:02:09Z"
Static configuration loaded {\"global\":{\"checkNewVersion\":true},\"serversTransport\":{\"maxIdleConnsPerHost\":200},\"entryPoints\":{\"http\":{\"address\":\":80\",\"transport\":{\"lifeCycle\":{\"graceTimeOut\":10000000000},\"respondingTimeouts\":{\"idleTimeout\":180000000000}},\"forwardedHeaders\":{},\"http\":{}},\"https\":{\"address\":\":443\",\"transport\":{\"lifeCycle\":{\"graceTimeOut\":10000000000},\"respondingTimeouts\":{\"idleTimeout\":600000000000}},\"forwardedHeaders\":{},\"http\":{}}},\"providers\":{\"providersThrottleDuration\":2000000000,\"file\":{\"watch\":true,\"filename\":\"/etc/traefik/dynamic.yaml\"}},\"log\":{\"level\":\"DEBUG\",\"format\":\"common\"},\"accessLog\":{\"format\":\"common\",\"filters\":{\"statusCodes\":[\"500-599\"]},\"fields\":{\"defaultMode\":\"keep\",\"headers\":{\"defaultMode\":\"drop\",\"names\":{\"Authorization\":\"redacted\",\"Cookie\":\"redacted\",\"Set-Cookie\":\"redacted\",\"X-Xsrftoken\":\"redacted\"}}}},\"certificatesResolvers\":{\"default\":{\"acme\":{\"email\":\"jovyan@jupyter.test\",\"caServer\":\"https://pebble/dir\",\"storage\":\"/etc/acme/acme.json\",\"keyType\":\"RSA4096\",\"httpChallenge\":{\"entryPoint\":\"http\"}}}}}"
\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://docs.traefik.io/contributing/data-collection/\n"
Starting provider aggregator.ProviderAggregator {}"
Start TCP Server" entryPointName=http
Start TCP Server" entryPointName=https
Starting provider *file.Provider {\"watch\":true,\"filename\":\"/etc/traefik/dynamic.yaml\"}"
Starting provider *acme.Provider {\"email\":\"jovyan@jupyter.test\",\"caServer\":\"https://pebble/dir\",\"storage\":\"/etc/acme/acme.json\",\"keyType\":\"RSA4096\",\"httpChallenge\":{\"entryPoint\":\"http\"},\"ResolverName\":\"default\",\"store\":{},\"ChallengeStore\":{}}"
Testing certificate renew..." providerName=default.acme
Starting provider *traefik.Provider {}"
Configuration received from provider file: {\"http\":{\"routers\":{\"default\":{\"middlewares\":[\"hsts\",\"scheme\"],\"service\":\"default\",\"rule\":\"PathPrefix(`/`)\",\"tls\":{\"options\":\"default\",\"certResolver\":\"default\",\"domains\":[{\"main\":\"local.jovyan.org\"}]}},\"insecure\":{\"middlewares\":[\"redirect\"],\"service\":\"default\",\"rule\":\"PathPrefix(`/`)\"}},\"services\":{\"default\":{\"loadBalancer\":{\"servers\":[{\"url\":\"http://proxy-http:8000/\"}],\"passHostHeader\":null}}},\"middlewares\":{\"hsts\":{\"headers\":{\"stsSeconds\":15724800}},\"redirect\":{\"redirectScheme\":{\"scheme\":\"https\",\"permanent\":true}},\"scheme\":{\"headers\":{\"customRequestHeaders\":{\"X-Scheme\":\"https\"}}}}},\"tcp\":{},\"udp\":{},\"tls\":{\"options\":{\"default\":{\"minVersion\":\"VersionTLS12\",\"cipherSuites\":[\"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\",\"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\",\"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\",\"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\",\"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\",\"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\"],\"clientAuth\":{},\"sniStrict\":true}}}}" providerName=file
Configuration received from provider default.acme: {\"http\":{},\"tls\":{}}" providerName=default.acme
Configuration received from provider internal: {\"http\":{\"services\":{\"noop\":{}}},\"tcp\":{},\"tls\":{}}" providerName=internal
No entryPoint defined for this router, using the default one(s) instead: [http https]" routerName=default
No entryPoint defined for this router, using the default one(s) instead: [http https]" routerName=insecure
Creating middleware" routerName=insecure@file middlewareName=pipelining middlewareType=Pipelining serviceName=default entryPointName=https
Creating load-balancer" serviceName=default entryPointName=https routerName=insecure@file
Creating server 0 http://proxy-http:8000/" serverName=0 entryPointName=https routerName=insecure@file serviceName=default
Added outgoing tracing middleware default" entryPointName=https routerName=insecure@file middlewareName=tracing middlewareType=TracingForwarder
Creating middleware" entryPointName=https routerName=insecure@file middlewareName=redirect@file middlewareType=RedirectScheme
Setting up redirection to https " entryPointName=https routerName=insecure@file middlewareName=redirect@file middlewareType=RedirectScheme
Adding tracing to middleware" routerName=insecure@file middlewareName=redirect@file entryPointName=https
Creating middleware" middlewareType=Recovery entryPointName=https middlewareName=traefik-internal-recovery
Creating middleware" entryPointName=http middlewareName=traefik-internal-recovery middlewareType=Recovery
Creating Middleware (ResponseModifier)" middlewareType=Headers routerName=default@file middlewareName=hsts@file entryPointName=http
Creating Middleware (ResponseModifier)" routerName=default@file middlewareName=scheme@file entryPointName=http middlewareType=Headers
Creating middleware" entryPointName=http serviceName=default middlewareName=pipelining middlewareType=Pipelining routerName=default@file
Creating load-balancer" routerName=default@file entryPointName=http serviceName=default
Creating server 0 http://proxy-http:8000/" serviceName=default serverName=0 routerName=default@file entryPointName=http
Added outgoing tracing middleware default" routerName=default@file middlewareType=TracingForwarder middlewareName=tracing entryPointName=http
Creating middleware" middlewareName=scheme@file middlewareType=Headers entryPointName=http routerName=default@file
Setting up customHeaders/Cors from %v{map[X-Scheme:https] map[] false [] [] [] [] 0 false [] [] false false map[] false 0 false false false false false false false}" entryPointName=http routerName=default@file middlewareName=scheme@file middlewareType=Headers
Adding tracing to middleware" entryPointName=http middlewareName=scheme@file routerName=default@file
Creating middleware" entryPointName=http routerName=default@file middlewareName=hsts@file middlewareType=Headers
Setting up secureHeaders from %v{map[] map[] false [] [] [] [] 0 false [] [] false false map[] false 15724800 false false false false false false false}" routerName=default@file middlewareName=hsts@file middlewareType=Headers entryPointName=http
Adding tracing to middleware" entryPointName=http routerName=default@file middlewareName=hsts@file
Creating middleware" entryPointName=http middlewareName=traefik-internal-recovery middlewareType=Recovery
Creating middleware" entryPointName=https middlewareName=traefik-internal-recovery middlewareType=Recovery
No default certificate, generating one"
Looking for provided certificate(s) to validate [\"local.jovyan.org\"]..." providerName=default.acme
No default certificate, generating one"
Creating middleware" serviceName=default middlewareType=Pipelining middlewareName=pipelining entryPointName=http routerName=insecure@file
Creating load-balancer" entryPointName=http routerName=insecure@file serviceName=default
Creating server 0 http://proxy-http:8000/" entryPointName=http routerName=insecure@file serviceName=default serverName=0
Added outgoing tracing middleware default" middlewareType=TracingForwarder entryPointName=http routerName=insecure@file middlewareName=tracing
Creating middleware" middlewareName=redirect@file middlewareType=RedirectScheme entryPointName=http routerName=insecure@file
Setting up redirection to https " middlewareType=RedirectScheme entryPointName=http routerName=insecure@file middlewareName=redirect@file
Adding tracing to middleware" entryPointName=http routerName=insecure@file middlewareName=redirect@file
Creating middleware" middlewareName=traefik-internal-recovery entryPointName=http middlewareType=Recovery
Creating middleware" middlewareType=Recovery entryPointName=https middlewareName=traefik-internal-recovery
Creating Middleware (ResponseModifier)" entryPointName=https routerName=default@file middlewareName=hsts@file middlewareType=Headers
Creating Middleware (ResponseModifier)" middlewareType=Headers routerName=default@file middlewareName=scheme@file entryPointName=https
Creating middleware" entryPointName=https routerName=default@file serviceName=default middlewareName=pipelining middlewareType=Pipelining
Creating load-balancer" routerName=default@file serviceName=default entryPointName=https
Creating server 0 http://proxy-http:8000/" serverName=0 entryPointName=https routerName=default@file serviceName=default
Added outgoing tracing middleware default" entryPointName=https routerName=default@file middlewareName=tracing middlewareType=TracingForwarder
Creating middleware" entryPointName=https middlewareName=scheme@file middlewareType=Headers routerName=default@file
Setting up customHeaders/Cors from %v{map[X-Scheme:https] map[] false [] [] [] [] 0 false [] [] false false map[] false 0 false false false false false false false}" middlewareType=Headers routerName=default@file entryPointName=https middlewareName=scheme@file
Adding tracing to middleware" entryPointName=https routerName=default@file middlewareName=scheme@file
Creating middleware" routerName=default@file middlewareType=Headers middlewareName=hsts@file entryPointName=https
Setting up secureHeaders from %v{map[] map[] false [] [] [] [] 0 false [] [] false false map[] false 15724800 false false false false false false false}" middlewareName=hsts@file entryPointName=https routerName=default@file middlewareType=Headers
Adding tracing to middleware" routerName=default@file entryPointName=https middlewareName=hsts@file
Creating middleware" entryPointName=https middlewareName=traefik-internal-recovery middlewareType=Recovery
Creating middleware" entryPointName=http middlewareType=Recovery middlewareName=traefik-internal-recovery
No default certificate, generating one"
Looking for provided certificate(s) to validate [\"local.jovyan.org\"]..." providerName=default.acme
Creating middleware" serviceName=default middlewareType=Pipelining middlewareName=pipelining entryPointName=https routerName=insecure@file
Creating load-balancer" entryPointName=https routerName=insecure@file serviceName=default
Creating server 0 http://proxy-http:8000/" serviceName=default serverName=0 entryPointName=https routerName=insecure@file
Added outgoing tracing middleware default" entryPointName=https routerName=insecure@file middlewareType=TracingForwarder middlewareName=tracing
Creating middleware" entryPointName=https routerName=insecure@file middlewareName=redirect@file middlewareType=RedirectScheme
Setting up redirection to https " routerName=insecure@file middlewareName=redirect@file middlewareType=RedirectScheme entryPointName=https
Adding tracing to middleware" middlewareName=redirect@file entryPointName=https routerName=insecure@file
Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=https
Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=http
Creating Middleware (ResponseModifier)" entryPointName=http middlewareType=Headers routerName=default@file middlewareName=hsts@file
Creating Middleware (ResponseModifier)" entryPointName=http routerName=default@file middlewareName=scheme@file middlewareType=Headers
Creating middleware" middlewareType=Pipelining middlewareName=pipelining entryPointName=http routerName=default@file serviceName=default
Creating load-balancer" entryPointName=http routerName=default@file serviceName=default
Creating server 0 http://proxy-http:8000/" serverName=0 entryPointName=http routerName=default@file serviceName=default
Added outgoing tracing middleware default" entryPointName=http routerName=default@file middlewareName=tracing middlewareType=TracingForwarder
Creating middleware" middlewareType=Headers entryPointName=http routerName=default@file middlewareName=scheme@file
Setting up customHeaders/Cors from %v{map[X-Scheme:https] map[] false [] [] [] [] 0 false [] [] false false map[] false 0 false false false false false false false}" entryPointName=http routerName=default@file middlewareName=scheme@file middlewareType=Headers
Adding tracing to middleware" routerName=default@file middlewareName=scheme@file entryPointName=http
Creating middleware" entryPointName=http routerName=default@file middlewareName=hsts@file middlewareType=Headers
Setting up secureHeaders from %v{map[] map[] false [] [] [] [] 0 false [] [] false false map[] false 15724800 false false false false false false false}" routerName=default@file middlewareName=hsts@file middlewareType=Headers entryPointName=http
Adding tracing to middleware" routerName=default@file middlewareName=hsts@file entryPointName=http
Creating middleware" entryPointName=http middlewareName=traefik-internal-recovery middlewareType=Recovery
Creating middleware" entryPointName=https middlewareName=traefik-internal-recovery middlewareType=Recovery
No default certificate, generating one"
Domains [\"local.jovyan.org\"] need ACME certificates generation for domains \"local.jovyan.org\"." providerName=default.acme
No default certificate, generating one"
Domains [\"local.jovyan.org\"] need ACME certificates generation for domains \"local.jovyan.org\"." providerName=default.acme
Loading ACME certificates [local.jovyan.org]..." providerName=default.acme
Looking for provided certificate(s) to validate [\"local.jovyan.org\"]..." providerName=default.acme
No ACME certificate generation required for domains [\"local.jovyan.org\"]." providerName=default.acme
Loading ACME certificates [local.jovyan.org]..." providerName=default.acme
Building ACME client..." providerName=default.acme
https://pebble/dir" providerName=default.acme
level=info msg=Register... providerName=default.acme
legolog: [INFO] acme: Registering account for jovyan@jupyter.test"
Using HTTP Challenge provider." providerName=default.acme
legolog: [INFO] [local.jovyan.org] acme: Obtaining bundled SAN certificate"
legolog: [INFO] [local.jovyan.org] acme: Obtaining bundled SAN certificate"
legolog: [INFO] [local.jovyan.org] AuthURL: https://pebble/authZ/Ry0-sVL2fgOhfZGNM6B-QHdSRaX3RucC_RfCMbhuWDI"
legolog: [INFO] [local.jovyan.org] acme: Could not find solver for: tls-alpn-01"
legolog: [INFO] [local.jovyan.org] acme: use http-01 solver"
legolog: [INFO] [local.jovyan.org] acme: Trying to solve HTTP-01"
legolog: [INFO] [local.jovyan.org] AuthURL: https://pebble/authZ/dlfrb8FCW9AeshOfOGuO_LEm8pt6TMRx1tVPFwvyvls"
legolog: [INFO] [local.jovyan.org] acme: Could not find solver for: tls-alpn-01"
legolog: [INFO] [local.jovyan.org] acme: use http-01 solver"
legolog: [INFO] [local.jovyan.org] acme: Trying to solve HTTP-01"
Retrieving the ACME challenge for token Gb56VvHeVTQV3EGQOIm1Y7wvuuS0atJGoWIhL1g0kWA..." providerName=default.acme
Retrieving the ACME challenge for token Gb56VvHeVTQV3EGQOIm1Y7wvuuS0atJGoWIhL1g0kWA..." providerName=default.acme
Retrieving the ACME challenge for token nxs1Z7D2pk44EjrOV__akhrdG2_WTHltyizUBn8ymlQ..." providerName=default.acme
Retrieving the ACME challenge for token Gb56VvHeVTQV3EGQOIm1Y7wvuuS0atJGoWIhL1g0kWA..." providerName=default.acme
Retrieving the ACME challenge for token nxs1Z7D2pk44EjrOV__akhrdG2_WTHltyizUBn8ymlQ..." providerName=default.acme
Retrieving the ACME challenge for token nxs1Z7D2pk44EjrOV__akhrdG2_WTHltyizUBn8ymlQ..." providerName=default.acme
legolog: [INFO] [local.jovyan.org] The server validated our request"
legolog: [INFO] [local.jovyan.org] acme: Validations succeeded; requesting certificates"
legolog: [INFO] Wait for certificate [timeout: 30s, interval: 500ms]"
legolog: [INFO] [local.jovyan.org] Server responded with a certificate."
Certificates obtained for domains [local.jovyan.org]" providerName=default.acme
Configuration received from provider default.acme: {\"http\":{},\"tls\":{}}" providerName=default.acme
Adding certificate for domain(s) local.jovyan.org"
No default certificate, generating one"
Creating middleware" routerName=insecure@file serviceName=default entryPointName=http middlewareName=pipelining middlewareType=Pipelining
Creating load-balancer" routerName=insecure@file serviceName=default entryPointName=http
Creating server 0 http://proxy-http:8000/" serverName=0 entryPointName=http routerName=insecure@file serviceName=default
Added outgoing tracing middleware default" entryPointName=http routerName=insecure@file middlewareName=tracing middlewareType=TracingForwarder
Creating middleware" entryPointName=http routerName=insecure@file middlewareName=redirect@file middlewareType=RedirectScheme
Setting up redirection to https " routerName=insecure@file middlewareName=redirect@file middlewareType=RedirectScheme entryPointName=http
Adding tracing to middleware" routerName=insecure@file middlewareName=redirect@file entryPointName=http
Creating middleware" middlewareType=Recovery entryPointName=http middlewareName=traefik-internal-recovery
Creating middleware" middlewareName=traefik-internal-recovery entryPointName=https middlewareType=Recovery
Creating Middleware (ResponseModifier)" entryPointName=http routerName=default@file middlewareName=hsts@file middlewareType=Headers
Creating Middleware (ResponseModifier)" middlewareType=Headers middlewareName=scheme@file entryPointName=http routerName=default@file
Creating middleware" entryPointName=http routerName=default@file serviceName=default middlewareName=pipelining middlewareType=Pipelining
Creating load-balancer" routerName=default@file serviceName=default entryPointName=http
Creating server 0 http://proxy-http:8000/" routerName=default@file serviceName=default serverName=0 entryPointName=http
Added outgoing tracing middleware default" entryPointName=http middlewareName=tracing middlewareType=TracingForwarder routerName=default@file
Creating middleware" entryPointName=http routerName=default@file middlewareType=Headers middlewareName=scheme@file
Setting up customHeaders/Cors from %v{map[X-Scheme:https] map[] false [] [] [] [] 0 false [] [] false false map[] false 0 false false false false false false false}" routerName=default@file middlewareType=Headers middlewareName=scheme@file entryPointName=http
Adding tracing to middleware" middlewareName=scheme@file entryPointName=http routerName=default@file
Creating middleware" middlewareType=Headers entryPointName=http routerName=default@file middlewareName=hsts@file
Setting up secureHeaders from %v{map[] map[] false [] [] [] [] 0 false [] [] false false map[] false 15724800 false false false false false false false}" entryPointName=http routerName=default@file middlewareName=hsts@file middlewareType=Headers
Adding tracing to middleware" routerName=default@file middlewareName=hsts@file entryPointName=http
Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=http
Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=https
Looking for provided certificate(s) to validate [\"local.jovyan.org\"]..." providerName=default.acme
No ACME certificate generation required for domains [\"local.jovyan.org\"]." providerName=default.acme
legolog: [INFO] [local.jovyan.org] The server validated our request"
legolog: [INFO] [local.jovyan.org] acme: Validations succeeded; requesting certificates"
```