mkcert
mkcert copied to clipboard
Chrome ERR_CERT_VALIDITY_TOO_LONG error
Chrome refuses to access the resource with NET::ERR_CERT_VALIDITY_TOO_LONG.
I can add an exception by using --unsafely-treat-insecure-origin-as-secure and clicking the "Advanced" > "Proceed to
It would be nice to have this working 100%, not just 90% :)
The cert I just generated has a validity range of exactly 10 years:
Not valid before: Wednesday, 13. January 2021 at 12:45:06 Central European Standard Time Not valid after: Monday, 13. January 2031 at 12:45:06 Central European Standard Time
Note: Chrome displays not only the cert, but also the rootCA in their error page.
Below you can find an example I just generated (the second cert is the rootCA.pem file contents):
~~Note: I have no idea if this is a bug/ regression where I can't find a way to debug and find it's root cause, or Chrome just updated in the background and this is expected default behavior.~~
Your connection is not private
Attackers might be trying to steal your information from traefik.bell.test (for example, passwords, messages, or credit cards). Learn more
NET::ERR_CERT_VALIDITY_TOO_LONG
Subject: mkcert development certificate
Issuer: mkcert root@devcerts
Expires on: Jan 13, 2031
Current date: Jan 13, 2021
PEM encoded chain:
-----BEGIN CERTIFICATE-----
MIIEQDCCAqigAwIBAgIQEtGKwB/F07dtGmZ3flpA0jANBgkqhkiG9w0BAQsFADBX
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExFjAUBgNVBAsMDXJvb3RA
ZGV2Y2VydHMxHTAbBgNVBAMMFG1rY2VydCByb290QGRldmNlcnRzMB4XDTIxMDEx
MzExNDUwNloXDTMxMDExMzExNDUwNlowQTEnMCUGA1UEChMebWtjZXJ0IGRldmVs
b3BtZW50IGNlcnRpZmljYXRlMRYwFAYDVQQLDA1yb290QGRldmNlcnRzMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsAnLQORBXCzVQLdAy6NsvSYM7Kfx
+GWJbTvHJz+QzwbFo6yXlcjpCTLAz0a6djR/pyFbXeAzfGsPfdgneWAzFWKaVgGN
ES6mGc1ul/BhxmUVPVbSJSiZviPXCd6uWJYcXS0zUNEYhGOB+ve8YdvfYu5PNr8A
qPwqhm/n++559OXTSHFyR6SfygMal8Seulm3aw4XnXhElWT42qsj0UjGY5Mnl02h
TZeDI3NAVuvPcqbJwI02rA9cs+N/HETqxDT1sJvCW7dW2gYjd58L/Iz4XoXPipkJ
JoEHZoSJ9VwFz6S9TJc+TtDwtkFk6e2PRpdaUQVNcCMFYkADFCGjDKopowIDAQAB
o4GdMIGaMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNV
HRMBAf8EAjAAMB8GA1UdIwQYMBaAFFIiavM5rChO0XwYvbaBcqjf4EXfMEQGA1Ud
EQQ9MDuCCyouYmVsbC50ZXN0ggliZWxsLnRlc3SCCWxvY2FsaG9zdIcEfwAAAYcQ
AAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAYEAPazkSSYItR239Dh8
8y02wRUSeqsOLI07susbIAWKFXd37SZF3NU4+v4NJwSX9SRGNDD1i3wwC+SaC9Rg
ty4hX4JEiUmiKeZPsD4tNgsPFPekEi/bmb5pSgbROtHTcAe3QfVuRjsKKtta5c5G
ST17LtQdajJ8Zc88pfrsxwrUnpBx3xgIlKJKQqtBvmxTGJA+11vbT9c8OfQ9PoK4
PxzhMskKRY6DWm5BkFd/x/kLdofSvDHMKa3k4zP2uiiTMgu42FforRTmo3odCK/b
40HQQ2Vyg4H5fKeO06RMDwk4rB57gWM4TB2VLwwF870y9BBPvYb5Rer+y418b20b
hfAOVtDbJWvxxKWhk1AFheFvFzUFFak4wkXPl/VBPRI+0mZVfqoiFLdQbTh5qoqz
j7Vz0t6wMzLePcpnixWQCb8x0bJIRkqIhG1VY5MFUruGFLAjmjUssgIS3NP95/Gw
IL+zhJSTFQ7sXzWdqwGjbpccClqJLGAmwvkN03eGqjlOkvgX
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEfjCCAuagAwIBAgIRAMM6NYCUwrVxff+UzfRfI70wDQYJKoZIhvcNAQELBQAw
VzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMRYwFAYDVQQLDA1yb290
QGRldmNlcnRzMR0wGwYDVQQDDBRta2NlcnQgcm9vdEBkZXZjZXJ0czAeFw0yMTAx
MTMwMDQzMjZaFw0zMTAxMTMwMDQzMjZaMFcxHjAcBgNVBAoTFW1rY2VydCBkZXZl
bG9wbWVudCBDQTEWMBQGA1UECwwNcm9vdEBkZXZjZXJ0czEdMBsGA1UEAwwUbWtj
ZXJ0IHJvb3RAZGV2Y2VydHMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB
gQDlThmign5Fwnhswp0ZYv7HFHrr8aFnDtmF+pJKcfetAlxAQwGQRaF8JLynDs+K
tZ8jQjQtEbsUVAvz4oc7r+RM4g5jncpk7lYRIyetnUs4BiOdnVcwo1vQ7Q5n64nT
QB/FXSvYjywYIKL0COft+bBtToD4fsVz1OYYON2x2jGcpyAhJ8L3p7VVRQlN4JQn
kJoVRjQKdgTygwj3AIoY8XS9Sw+BQtvS5Mbaq9QJkbt7v8eB7xt0l51mCEYMg1ee
KuBtlHAKafT5vtNpAmdk2qc+uRhUhG4SLGoqwfUyj7LCBu9pVt46WUur0Mo+m7qB
3r9aTqRqEU0qdmh5VO2j5iPGQj/pVoIEpWEJ00aL6NkJzHcJfL/VpfZKQhbVUAw4
ut3Mo/IP00rNaqYcuk/EwSnbt+azNOgdrP77kIZCqH119yxcril9I7LpftpoJkhE
Nwc0WiTQB5yObfqTgGNOrg1YoEty5Rg8OU4DG3459JFbqsRoZgMwsIiw05tUZ493
B2ECAwEAAaNFMEMwDgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQAw
HQYDVR0OBBYEFFIiavM5rChO0XwYvbaBcqjf4EXfMA0GCSqGSIb3DQEBCwUAA4IB
gQB/RohLFOG2UBUXfaRKTZoLL4RqbBkgmqQ18DoKHupuTBtppiPYYfunXK4e+Kze
YAx7H6wNIHw813ZzwlRkkcpW9zy/m+SrAzt+KCSUJwhCOBET5PAURplnra3KRY0y
tXE5KyQ9ixaLsE5/W1PYkSZ8VxSbwyxC+cZga+621Yx4g0bSjcGE43khfKPrNCjG
VZ1VqRQScJJ6qiFps3EbnOR9BrPoCLRqDbZEEESRGk+Gq7WEt3UVNolBEvJL8NNE
T2Zd27FXxx7dEaqO3YGmnIUfR2sQ1pFgxz8pPjWHAAigEKYFoGcxzUvVHWA7QNi8
QeTKrjxEX92s9LhcoUXie7GcuD4Zm6VSt4/2KR/4peK6fgGAasU34wEnqIc2y2qV
+0Cog7lHDjYdYC0qj2e8haYBe94STPYv9DMxbtq1XxDB0tJbqA1Aj0hABky1/RY5
eTOLw5lhpNOSe38xWUSHQUI86clHS2Es2mpyLRCKLzo2RTTWAjynS3oH5TX/QwVI
tEw=
-----END CERTIFICATE-----
The fingerprints are correct and matching. Here're the scripts to check.
#!/usr/bin/env bash
CERTIFICATE=${*?Certificate missing}
openssl x509 -noout -in "${CERTIFICATE}" -fingerprint -sha1
#!/usr/bin/env bash
CERTIFICATE=${*?Certificate missing}
keytool -printcert -v -file "${CERTIFICATE}"
Setup
The whole test/ demo setup contains out of Alpine Linux containers. The containers are orchestrated using Docker Compose. All public facing containers share the same network and a named volume:
---
# $ROOT_DOMAIN and $MKCERT_TAG are set inside `.env`
version: '3'
services:
# Local development certificates (mkcert)
devcerts:
image: "kklepper/mkcert_a:${MKCERT_TAG:-alpine}"
hostname: "devcerts"
command:
- /bin/sh
- -c
- "/root/mkcert -cert-file $${CAROOT}/cert.$${CERT_FILENAME} -key-file $${CAROOT}/key.$${CERT_FILENAME} '*.${ROOT_DOMAIN}' ${ROOT_DOMAIN} localhost 127.0.0.1 ::1"
networks:
- certs
ports:
- "2443:443"
working_dir: /usr/local/share/ca-certificates
volumes:
- type: volume
source: dev-cert-storage
target: /usr/local/share/ca-certificates
volume:
nocopy: false
environment:
- CAROOT=/usr/local/share/ca-certificates
other_container:
volumes:
# Certificates for local development.
- dev-cert-storage:/usr/local/share/ca-certificates:ro
volumes:
dev-cert-storage:
driver_opts:
type: none
o: bind
device: ${PWD}/certs
Process:
- The container simple receives a
docker-compose up devcertsand then creates the certs. It saves it to the named volume, which then shared. - Then the cert gets copied to the mkcert CA root dir:
cp ./root* "$(mkcert -CAROOT)" - After this happened, the certs get added to the keychain in macOS:
cd ./path/to/certs; mkcert -install.
The local CA is now installed in the system trust store! π
The local CA is now installed in the Firefox trust store! π
The local CA is now installed in Java's trust store! π
Provider: Docker Compose/ Docker using The mkcert image by kklepper.
System
mkcert:
$ mkcert --version
v1.4.3
Host OS: MacOS 11.1 Big Sur Google Chrome: Version 87.0.4280.141 (Official Build) (x86_64) Firefox: 84.0.2 (64-bit) Safari: Version 14.0.2 (16610.3.7.1.9)
Might be related to:
- https://github.com/FiloSottile/mkcert/issues/313
Note: Verbose process description, keywords, etc. are meant to offer better indexing to help others find this issue and hopefully also find some help.
As it turns out, Google limits cert validity to 398 (397) days, effective with 2020-09-01. Announcement in full length here. This results in mkcert being effectively broken for Chrome/ Chromium right now.
Pointer to the cert.go line here/ 1.4.3.
397 (considering leap seconds w/ 86,400 sec/d) days equals 1 year, month, 1 day. The following change is needed and assumes that every month has 31 days (to be on the safe side).
- expiration := time.Now().AddDate(2, 3, 0)
+ expiration := time.Now().AddDate(1, 1, 1)
@FiloSottile Could you please take a look at the issue and the provided PR? Thanks in advance!
That Chrome restriction only applies to publicly trusted certificates. There is macOS-level restriction which we have been first working around and then complying with for a long time. Judging from your NotBefore and NotAfter, you are using a very old version of mkcert. Please update and check if the issue persists.
The version is correct and v1.4.3 as reported above. But you have been right regarding the date. I double and tribble checked and noticed at some point that even if I wipe clean everything, the NotBefore date stayed the same old date for every newly generated rootCA.pem. At around 10 repetitions including several restarts, I decided to generate everything new, but to not clean the system store via the keyChain app. And all of a sudden I had two certs and one of them had the current date set as NotBefore date. I couldn't find any clue if there's some cache or hidden store somewhere. Searching the whole drive for some rootCA.pem returned zero matches. No idea what's the reason behind this (OS etc as reported in the initial comment). Any clues appreciated as I'd really like to understand what's going on here. Thanks in advance.
I really don't see how mkcert v1.4.3 could have generated that certificate. Are you sure you're not using a different version of mkcert inside a container or something like that?
@filippobuletto yes, I am sure about that. But please don't get me wrong here: I assume that this does not happen because of mkcert.
Below you can find a cert that I generated yesterday on 2021/01/25. The expiration and not valid before dates are set to 2021/01/22, which is 3 days before the date I generated the cert.

I did a fresh re-install mkcert and I'm on version 1.4.3. The expiry date of the cert is March 08, 2031. I think they fix does not work in the latest version.
I hope to not up a stale issue when not necessary but FYI, kklepper/mkcert_a Docker image downloads mkcert 1.3.0 (you can run docker pull kklepper/mkcert_a:alpine && docker inspect kklepper/mkcert_a:alpine and see the Cmd part to check this, I would add this is not a best practice to download the binary at container startup instead of integrating the binary inside the image).
I recommend you to use flesch/mkcert which has a 1.4.3 tag or unsanctioned/mkcert with the v1.4.3 tag.
Both are recent images so I don't know if maintainers will provide updates in the future but at least, they provide for now the latest mkcert version.
EDIT: I see you installed latest mkcert locally, so you don't need to use the Docker image. Or maybe I don't understand what you did, in that case I would be happy to have more details to understand the bug you got.
I recommend you to use flesch/mkcert which has a
1.4.3tag or unsanctioned/mkcert with thev1.4.3tag. Both are recent images so I don't know if maintainers will provide updates in the future but at least, they provide for now the latestmkcertversion.
Trying to use flesch/mkcert for my certificate. I want to combine it with my flask application which is also running in a docker container. After building both my flask app over localhost and mkcert I want to access them via my local macOS machine. As I am pretty new to docker i am trying to use two Dockerfiles and combine them in a docker-compose.yml
from flesch/mkcert:latest
WORKDIR /opt/mkcert/data
VOLUME ["/opt/mkcert/data"]
CMD ["mkcert", "-install", "localhost", "*.localhost", "127.0.0.0", "0.0.0.0"]
Unfortunately when the cert is being generated i get the message:
Created a new local CA π₯
Installing to the system store is not yet supported on this Linux π£ but Firefox and/or Chrome/Chromium will still work.
You can also manually install the root certificate at "/.local/share/mkcert/rootCA.pem".
Also Chrome is giving me the NET::ERR_CERT_AUTHORITY_INVALID - error. For me it is clear, that my CA is not valid but I have no idea what else I have to do.
Any ideas from your side?
@cemiboii if you generate certificates in the container, Chrome (and any other browser) won't "know" the certificate.
As you certainly know, mkcert generate a certificate authorithy (CA) which in turns is used to sign domains certificates. Your browser just need to know the certificate authority.
When using mkcert on the host (not on a container), it can install the root CA in your system and browsers automatically. But if you use mkcert on the container, mkcert will try to install the root CA in⦠The container. Your browsers are not in the container.
But don't worry, there is a workaround! You'll just need to install the root CA manually.
You need to create volumes in your mkcert service in your Compose file and set a CAROOT environment variable for this service to use the volume as the certificates output. mkcert --help give you little information about CAROOT environment variable.
Then you'll need to manually import the root CA in your browser(s) because, as I said, mkcert can't do it automatically from the container (I recommend you to set a TRUST_STORES variablew to an empty string so mkcert won't even try to install certificates in the container, it's not required). If you don't know how to import a certificate authority in Chrome, you can find easily by searching "chrome import root ca" (here is an example documentation).
I hope those information help you.
Tip about Docker: do not use :latest images but use a specific version, so you update manually when required. It prevents you from receiving unwanted updates (which can break the API).
Another tip: using volumes with Docker on macOS can be really slow. For certificates, you won't care because it's not read/write intensive but don't be surprised if you use volume for more disk intensive container.
@sambonbonne thanks a lot for your detailed answer.
In the meantime I was trying a new approach with this solution #169 and I would say that it is working.. at least for now.
I also have a volume and am able to access both rootCA.pem and rootCA-key.pem and set TRUST_STORES to an empty string.
My container output is now the following:
docker logs mkcertiiii2 -f
+ mkdir -p /opt/mkcert/data
+ cd /opt/mkcert/data
+ wget -q -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64
+ chmod +x mkcert
+ export 'CAROOT=/cem/.local/share/mkcert'
+ ./mkcert -CAROOT
/cem/.local/share/mkcert
+ ./mkcert -install
Created a new local CA π₯
The local CA is now installed in the system trust store! β‘οΈ
+ ./mkcert localhost '*.localhost' 127.0.0.0 0.0.0.0
Created a new certificate valid for the following names π
- "localhost"
- "*.localhost"
Warning: many browsers don't support second-level wildcards like "*.localhost" β οΈ
- "127.0.0.0"
- "0.0.0.0"
Reminder: X.509 wildcards only go one level deep, so this won't match a.b.localhost βΉοΈ
The certificate is at "./localhost+3.pem" and the key at "./localhost+3-key.pem" β
It will expire on 20 October 2023 π
Even though everything looks good, after importing my rootCA in my macOS keychain I still get the NET::ERR_CERT_AUTHORITY_INVALID error. When I am checking the information of my rootCA cert and compare it with the certificate of my localhost they differ. Maybe I am doing it wrong or im just a big nooby in this case.
Okay I think I just found out, why I still got the certificate error.
Just installed mkcert on my local machine, set CAROOT to my shared folder / volume where my rootCA is located and did a mkcert -install on my local machine. Now it's working properly as it should.
I think that's it. Thanks again for helping me out on this one.
@cemiboii if you generate certificates in the container, Chrome (and any other browser) won't "know" the certificate.
As you certainly know,
mkcertgenerate a certificate authorithy (CA) which in turns is used to sign domains certificates. Your browser just need to know the certificate authority. When usingmkcerton the host (not on a container), it can install the root CA in your system and browsers automatically. But if you usemkcerton the container,mkcertwill try to install the root CA in⦠The container. Your browsers are not in the container. But don't worry, there is a workaround! You'll just need to install the root CA manually.You need to create
volumesin yourmkcertservice in your Compose file and set aCAROOTenvironment variable for this service to use the volume as the certificates output.mkcert --helpgive you little information aboutCAROOTenvironment variable. Then you'll need to manually import the root CA in your browser(s) because, as I said,mkcertcan't do it automatically from the container (I recommend you to set aTRUST_STORESvariablew to an empty string somkcertwon't even try to install certificates in the container, it's not required). If you don't know how to import a certificate authority in Chrome, you can find easily by searching "chrome import root ca" (here is an example documentation).I hope those information help you.
Tip about Docker: do not use
:latestimages but use a specific version, so you update manually when required. It prevents you from receiving unwanted updates (which can break the API).Another tip: using volumes with Docker on macOS can be really slow. For certificates, you won't care because it's not read/write intensive but don't be surprised if you use volume for more disk intensive container.
What if mkcert was installed inside a WSL container.. how do we get the CA into the browser from there?