Scheduled posts fail to post at their time

We’ve had this issue from the very beginning, but what’s happening is if we schedule a post it doesn’t actually post at the specified time.

I read through the comment here: Scheduled Posts don't Publish and it seems the solution there was a custom nginx config. We’re using the standard ghost-cli install that doesn’t have any custom nginx configuration.

All that I can find is that our log files show a 404 when the schedule comes up

[2019-01-09 17:50:00] INFO "GET /ghost/api/v0.1/schedules/posts/5c362fa881df4c55c8d6db92?client_id=ghost-scheduler&client_secret=(secret)" 404 3ms

I don’t know where else to find deeper information about the error though. Thoughts? Where can I look.


Not sure exactly what you mean by this. But it was installed using ghost-cli and using an external MySQL database (Amazon RDS). Here is also my config.production.json.

  "url": "(url)",
  "server": {
    "port": 2369,
    "host": ""
  "database": {
    "client": "mysql",
    "connection": {
      ... cred
  "mail": {
    "transport": "SMTP",
    "from": "(email)",
    "options": {
      "host": "",
      "port": "25",
      "auth": {
        ... cred
  "logging": {
    "transports": [
  "process": "systemd",
  "paths": {
    "contentPath": "/data/ghost/content"
  "bootstrap-socket": {
    "port": 8000,
    "host": "localhost"

The only error I see was included in my original post. It shows a 404 at the time of the scheduled post calling out the /schedules/post endpoint.

[2019-01-09 17:50:00] INFO "GET /ghost/api/v0.1/schedules/posts/5c362fa881df4c55c8d6db92?client_id=ghost-scheduler&client_secret=(secret)" 404 3ms

If there is anywhere else I should be looking, let me know.

Just to quickly update on this.

Does anyone know where I can look to find further information about this 404 error?

We’re scheduling multiple posts and week and having to manually publish each one of them right now.

I can’t verify this for certain cos you’ve not included the key info - but I’m guessing your URL in the config is set to HTTP, not HTTPS.

You need to change your URL to https e.g. ghost config url and restart Ghost with ghost restart.

The mechanism used by Ghost to publish scheduled posts, is to make an API call to:

PUT /ghost/api/v0.1/schedules/posts/[id]

In the logs above, we see a GET, rather than a PUT, which indicates that the PUT probably got redirected, I’m guessing from the default of http to the API’s preferred https, but in the act of redirecting gets converted from PUT -> GET, and there is no GET method for that endpoint.

Thank you! That gave me the information I needed to track this down.

It came down to the fact that there was an SSL redirect in the nginx configuration. Once the PUT call came in and was redirected it was turned into a GET. I added an exclusion for the /schedules/posts/ endpoint and was able to get around the issue.

The correct fix is to configure your URL to be HTTPS in the Ghost config so that all traffic is HTTPS, and HTTP traffic is redirected. It’s better for SEO, and will likely be the only valid option for production very soon.

We’re already using SSL and redirecting automatically if it’s not SSL. The SSL is setup at the load balancer outside of this machine. The redirect is setup in nginx on the machine.

However, Ghost itself is setup for non-SSL because if I enable SSL it tries to do a redirect itself on the local port and even if I allow that it fails since there are no certificates on this machine.

If there was a way for me to tell ghost that it’s url is https but that it’s not doing the SSL itself (i.e, don’t perform your own redirect) then that would solve this problem. I’m not sure how others with an external SSL termination are handling this at the moment.

Ghost redirecting incorrectly when you set the URL (correctly) to https, is a symptom of a misconfigured proxy. My first guess is that X-Forwarded-Proto is set to http instead of https.

In any standard setup, nginx is used as a reverse proxy and ensures Ghost gets what it needs. It doesn’t really matter if you put a load balancer, or a cache or Cloudflare or another 7 proxies in front (although load balancing Ghost across multiple instances will cause other issues) as long as nginx is configured correctly.

The proxying logic in Ghost comes from express, and is explained here:

Alternatively, share your configs, and we can take a look :slight_smile: .

Ah! Yup, that’s right it looks like our configuration wasn’t passing the HTTP property properly. We previously had this in the nginx configuration

proxy_set_header X-Forwarded-Proto $scheme;

and it was changed to this

proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;

Here is the full configuration

server {
    listen 80;
    listen [::]:80;

    server_name blog.(oursite).com;
    root /data/ghost/system/nginx-root;

    location / {
        if ($http_x_forwarded_proto != 'https') {
            rewrite ^ https://$host$request_uri? permanent;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;

    location ~ /.well-known {
        allow all;

    client_max_body_size 50m;

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