Failed to load resource: net::ERR_CERT_DATE_INVALID

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. crt.sh | example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:tpmeyer.xyz

I ran this command:from browser go to tpmeyer.xyz/twordle

It produced this output:in the console, I see Failed to load resource: net::ERR_CERT_DATE_INVALID

My web server is (include version):nginx version: nginx/1.24.0 (Ubuntu)

The operating system my web server runs on is (include version):Ubuntu 24.04.1 LTS

My hosting provider, if applicable, is:hostinger

I can login to a root shell on my machine (yes or no, or I don't know):YES

I'm using a control panel to manage my site (no, or provide the name and version of the control panel):NO

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot):
certbot 2.9.0

My certificates are all valid and up to date, as verified with:
openssl s_client -connect tpmeyer.xyz:443 -showcerts
I reissued the certificates a couple days ago hoping that would solve the problem, but to know avail.

I get this same error from multiple clients, including phones, so I don't think it's a browser cache issue.

The only thing I can think of is that your cert doesn't include the "www".
And your link to that page includes the "www".

Since both names resolve to that IP:

Name:    tpmeyer.xyz
Address: 89.116.49.220

Name:    www.tpmeyer.xyz
Address: 89.116.49.220

I would include the "www" in the cert.

2 Likes

I don't see where my link to that page includes www.
The website was working for a couple months, and then stopped for no discernible reason.

I also don't see "www" anywhere in your coding.

But... that's the only plausible reason I can think of.
[sorry, I may need a brain (software) upgrade - lol]

1 Like

Can you send the full URL that produces that error?

1 Like

All the apps on tpmeyer.xyz have the same problem. Here's a couple:
https://tpmeyer.xyz/straq/

Those URLs work just fine?

Are you connecting to the correct IP address? I.e., 89.116.49.220?

They seem to work from the user end, but as stated, when you look in the console (ctrl-shift-J) you see the error, and the data are not being written to the server, as the node.js calls are failing.

Ah, yes, some scripted URL requests. If you look at the "Network" tab, you'd see that the following URL is failing:

https://tpmeyer.xyz:3000/player_number

(Turbo Wordle)

Notice the 3000 port? Apparently, Express is directly accessible from the world wide web instead of going through your nginx. And Express is incorrectly configured it seems.

a) Not sure if you want to have Express directly accessible from the public internet on port 3000;
b) If you do, you should make Express serve the correct certificate.

For that "straq" thingy, the failing URL is:

https://tpmeyer.xyz:4431/api/load-markers

Which is a totally different port..? But also Express..

Weird.

I'm not sure it's wise to have multiple applications ("/twordle/" and "/straq/") have their special requests ("player number" and "load markers") using different ports. My recommendation would be to also have these requests behind the nginx proxy and have it also separated from each other by either a separate hostname or a separate path.

4 Likes

That sounds like the right idea, but I'm not sure how to "put the requests behind the nginx proxy"..
Here's the code I currently have, which seems to be the wrong idea...

===================
app.get('/api/load-markers', (req, res) => {
    res.set('Content-Type', 'application/json'); // Set the Content-Type header
    res.set('Access-Control-Allow-Origin', '*'); // Set the Access-Control-Allow-Origin header
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    db.query('SELECT address, lat, lng, owner, email,phone, flags.description as flag, flags.color, flags.letter, flag_id, knocker_id, manager_id, contract_id, equipment_id, has_audio FROM HOUSES, FLAGS WHERE active=true and flag_id = flags.id ', (error, results) => {
        if (error) { 
            console.error('Error fetching markers:', error);
            res.status(500).json({ error: 'Internal server error' });
        } else {
            res.status(200).json(results.rows);
        }
    });
});

const httpsOptions = {
  cert: fs.readFileSync('fullchain.pem'),
  key: fs.readFileSync('privkey.pem')
};

const httpsServer = https.createServer(httpsOptions, app);

// Start HTTPS server
httpsServer.listen(PORT, () => {
    console.log(`HTTPS Server is running on https://tpmeyer.xyz:${PORT}`);
});

=============================================

I think that's just the Node.JS/Express server part.

I don't know anything about NodeJS and frankly I want to keep as much away from Node as is possible, but I think the client side part is somewhere else?

Where are those file located?

3 Likes

Ah yes, I ignored the whole certificate thing :stuck_out_tongue: (Because I still think Node should be behind nginx.)

2 Likes

Probably loading old copy of that cert.

find / -name fullchain.pem

4 Likes

Yes, it was loading an old copy of the certificate. It seems like bad design, because the certificate is owned by root, but I don't want to run my scripts as root, so I have to make a copy of the certificates and change permissions. So I have to remember that each time my cerrtifcates renew, I have to copy them over again. There must be a better way!!

1 Like

Use Certbot's --deploy-hook to copy files and change permissions automatically on successful renewals.

4 Likes

As @Nekit says, certbot (and other clients) will let you run commands when certs are issued which could handle this. But the better answer yet is to do what @Osiris suggests and put Express behind Nginx. Once you've done that, Express won't need to deal with the cert and key at all, and therefore there won't be any reason to try to pass them to Express.

5 Likes

If you could unpack what you mean when you say "put Express behind nginx", I'm happy to rewrite my code to do so, but I don't know where to start. This is my first javascript program, and I was flailing all along the way.

You can put your application behind nginx by configuring a reverse proxy. This short guide explains how.

3 Likes