Fatal error: tls: failed to find any PEM data in certificate input

1. The problem I’m having:

I am running caddy in a docker container via docker-compose I can make everything work in http but if I try to enable https I get the below error.

I have included all the configs and relevant information below but basically I am trying to host a website with an app in it. The application does have a native TLS mode that ask for the SSL_CERT and SSL_KEY. I believe I found the correct cert files located at caddy_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/myapp.backendlinux.com/. If I use this information I get the error I mentioned about no PEM data in certificate input.

First I am not positive this is the correct cert files but from my research it appears they are.

There is much more information available I can supply but did not want to go overboard but I have tried multiple different ways of trying to resolve this briefly I will list them below a very brief reason for abandoning those routes.

  • Serve site app as http this works but causes mixed content error in the browser ok for me not ok for random user/visitors.
  • Serve site and app as http this works perfectly sadly how everything was tested I didn’t think there would be this much of an issue rolling it over to HTTPS. Main reason for doing so seo and most normal users get scared away when a browser says this site could steal your info.


And finally.

  • Serve app as http and proxy this would be my preferred way of doing this but it appears the application checks the origin and if it receives a request ie. served as http but receives an https request it errors out. My understanding was caddy when used as a reverse_proxy pass the requests upstream as http but that does not seem to be true or there is other header details causing the request be registered as https.

I tried multiple different combinations of header_up and header combinations change the https request to http but I don’t think this is the correct way to go about this but if I am wrong tell me and I will dig into making it work that way.

  • Also has the same issues with mixed content errors.

2. Error messages and/or full log output:

fatal error: tls: failed to find any PEM data in certificate input 

3. Caddy version:

Caddy v2.6.4

4. How I installed and ran Caddy:

docker-compose pull
docker-compose up -d

a. System environment:

Debian 6.1.37-1 (2023-07-03) x86_64 GNU/Linux
Linux v6.1.0-10-amd64
Docker version 20.10.24+dfsg1, build 297e128

b. Command:

docker-compose up -d

c. Service/unit/compose file:

version: '3.7'

      image: caddy:latest
      restart: unless-stopped
        - "80:80"
        - "443:443"
        - "443:443/udp"
        - ./access.log:/var/log/access.log
        - ./Caddyfile:/etc/caddy/Caddyfile
        - ./html:/srv
        - caddy_data:/data
        - caddy_config:/config

      image: myapp
      restart: unless-stopped
        - "8080:8080"
         ORIGIN: https://myapp.backendlinux.com
         PORT: 8080
         POSTGRES: postgres://postgres:postgres@db:5432/myapp?sslmode=disable
         GITHUB_KEY: <redacted>
         GITHUB_SECRET: <redacted>
         ENABLE_LOGGING: 'true'
         SSL: 'true'
         SSL_CERT:  caddy_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/myapp.backendlinux.com
        SSL_KEY:  <same>
      image: postgres:12.5-alpine
      restart: unless-stopped
        POSTGRES_DB: 'myapp_db'
        POSTGRES_USER: 'postgres'
        POSTGRES_PASSWORD: 'postgres'
        - myapp_db:/var/lib/postgresql/data

                 external: true
                 external: true
                 external: true

d. My complete Caddy config:


myapp.backendlinux.com {

        reverse_proxy myapp:8080


backendlinux.com {

        header X-Content-Type-Options "nosniff"
        header Cache-Control max-age="31536000"

        log {
                format json 
                output file /var/log/access.log {




5. Links to relevant resources:

6. Things I have tried:

If I am correct I and that cert files I noted earlier are the correct files which again I am not sure they are I have tried these things.
cat appmy.website.com.crt myapp.backendlinux.com.key > cert.pem See stackoverflow lilnk

I have also tried multiple different version of this approach. I believe the certs and keys produced by caddy are of the ec type not the rsa atleast the key is ec.

I also tried using openssl to convert the crt and key.
openssl x509 -inform DER -in myapp.backendlinux.com.crt -out cert.pem -text

If I am correct about this being the correct approach the second stackoverflow link I posted about refrences so information about converting ec keys to PEM data but I didn’t really understand it and then came here.

Thank you

Any links or pointers or just telling I am wrong I should do this a different way would be greatly appreciated.

Ok I got more of this working by moving the certs to the root of the container but now I get an error that says certificate is valid for myapp.backendlinux.com, not myapp".

I working on the assumption that this is a issue from when I originally created the certs. But still trying to figure this out.

It’s correct to proxy over HTTP from Caddy to your app. Caddy terminates handles HTTPS and terminates TLS, then proxies to your app over HTTP.

It’s generally incorrect to try to reach into Caddy’s storage manually. It’s managed storage, and the paths to the certs/keys are not consistent because Caddy may choose to use a different issuer than Let’s Encrypt depending on availability (i.e. ZeroSSL currently, by default).

Don’t bind this port to the host. Removing this will ensure your app can only be accessed through Caddy, and never directly, ensuring that traffic is always encrypted.

Thank you sir I think I am going to have to start with new certs anyway not sure if you saw my last post I was able to get part of it work my move the a copy of the certs.

If I can ask when the certs are issued is it correct that there should be a cert for myapp.backendlinux.com or should it be just myapp.

Don’t move or copy the certs. They expire after 90 days, so if you do that, you’re forcing yourself to continually re-copy and move the certs. Don’t depend on that.

Like I said, don’t reach into Caddy’s storage. Let Caddy do its thing.

Certs are always for the full domain name. It wouldn’t make sense for a cert to exist for myapp because that doesn’t mean anything. myapp.backendlinux.com is a domain that can be found in public DNS, which is meaningful.

Its working I deleted the certs i moved and removed the 8080 I think it was trying to connecting directly causing the issue. Now only issue is a couple small error about requesting css from http. But hopefully I can figure those out.

1 Like

That fixed it I love you do you have a kofi or site I am more then happy to repay you any way I can. Please don’t hesitate to ask.

The best thing you can do is sponsor the project: Sponsor @mholt on GitHub Sponsors · GitHub

I will do that and again thank you I really think it was that port being exposed that screwed me up thank you thank you may all your wishes and dreams come true.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.