Scheduled worker not called at defined time

I have a really simple worker which is called via http and by a cron defined on cf worker panel.

Basically what my worker should do it’s to do a http request to my api to execute cron jobs at my server.

Unfortunately, I’ve been testing it for a few weeks and the cron scheduler is not calling my work, however when I access it by it http route, it works.

This is my cron: 35 13 * * sat,fri,mon

My code:

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request))
   })
  
addEventListener("scheduled", event => {
  event.waitUntil(handleRequest(event))
  } )



async function handleRequest(request) {

   const req = await fetch("https://myapi/api/cron")
     if(req.ok){
       return new Response("Ok")
     }
     return new Response("Error")
}

I reckon this is a bug with CF workers, because when I access my worker by its url it works and my api is called.

I already tried to change my cron and I did it, but without any success.

I would be glad to have any help with this issue! Thanks in advance!

Greetings!

Thanks for asking.

I’ve had a simple one too, which wasn’t working well :smiley:

My working one - except my Cloudflare Worker was pointed to the URL which executed a PHP script on the server side (to generate something else) and returned the content for me as “debug info” like “OK!”, that way I do not need to check the resposne as it’s always HTTP 200 (as far as the origin is working) + knowing the server setup and time needed to be executed (along the 100s of Cloudflare timeout):

addEventListener('scheduled', event => {
    event.waitUntil(triggerEvent(event.scheduledTime))
})

async function triggerEvent(scheduledTime) {
    return fetch(`https://myapi/api/cron`)
}

Only the thing was, I managed to see Challenged or Blocked request coming from Cloudflare at Firewall Events due to my Security settings at Cloudflare for that domain (empty user-agent, etc.).

I tracked that for 24 hours - as my worker runs every 5 minutes, it was easy to detect the IP from which it triggers.

Therefore, I’ve added the IPv6 of the Cloudflare Worker to Firewall - > Tools → IP Access Rules and issue was gone, Cloudflare Worker still working since then :slight_smile:

Thanks for the quick answer! My server is a next.js server running on vercel.

I tested a cron job to run every 15 minutes just for test purposes and it was working as expected. But, when I changed it to my needs with 35 13 * * sat,fri,mon, it doesn’t works.

Your code works, but what doesn’t works it the cron which is not called by cf.

1 Like

Thank you for feedback.

That’s a bit interesting :thinking:

Maybe a timezone difference(s) - for me I remember when looking when it triggered it was +/- 2 hours GMT - if it could be related to this somehow?, or it actually doesnt’ trigger at all, as you say at the specific given date & time?

Might just not support sat,fri,mon, maybe change the cron to be 35 13 * * 1,5,6?

I could raise it to the team, but this test would be good. Maybe use a relatively close time in the same format. Maybe try also with just one day, instead of multiples.

1 Like

It doesn’t trigger at all. I’m suspecting it’s bug, because when I check the scheduled logs panel, it shows that my function was triggered, but it wasn’t.

I’m deploying only using the CF UI. I’m not using wrangler cli. Furthermore, when I open the CF UI to test the scheduled cron, when I click on test button, the first click doesn’t call my function, because nothing is showed on network console neither on logs console. My worker is only called after second click on test button. (This behavior is really strange)

I’m suspecting that the same is happening with my worker, it is not called at a specific time, but when it’s called sequentially by the cron, the function is triggered.

Before I’m using 35 13 * * sat,fri,mon I was using 35 13 * * 1,5,6.

I’m only changed it, because I thought it could be wrong. So instead of using a Cron expression, i tried to use the Cron expression generator on the workers UI, and it returned this one 35 13 * * sat,fri,mon.

I have tested many times the trigger. When i was testing at each 5 minutes it was working, but i don’t need to run my worker each 5 minutes.

But when i changed it to 35 13 * * sat,fri,mon it didn’t work anymore. On the UI it appears like if it worked, but it didn’t.

1 Like

Scheduled events don’t accept responses as return values. With the current code, even if the response isn’t OK, the UI will show an success status. If you want it to show an error, you’ll have to throw an exception.

addEventListener("scheduled", event => {
  event.waitUntil(handleScheduled(event))
})

async function handleScheduled(event) {
    const req = await fetch("https://myapi/api/cron")
     if(!req.ok){
       throw new Error("not ok");
     }
}
3 Likes

Thanks for the tip and for the answer!

I updated my code with the example provided by you. However I don’t want to return a error nor a success log.The issue I’m having is that my scheduled job is not being called by CF workers.

1 Like

May I ask if the URL route is correctly set and in “production” on your domain?

Yes, the url is correct, and it’s on production. If i access my cron url directly, or by accessing my cf worker by it’s url adress, it is called. I could send the link here, but i think it would not be safe, because it will be public and at moment i don’t have any token accesss based control.


This is what happens when i trigger my scheduled event for the first time. After a second click it’s called normaly, i dont’t know, but i’m suspecting that the same is happening with my worker.

I have just make a another test. I removed all cron that i had set before and I created a new one with this expression: */5 * * * *. I don’t know if it’s a normal behavior or not, but i created this one at 15:20, and it was only called at 15:40, and now it’s been called every 5 minutes since then.

@fritex @matteo @aloyd

I deleted my previous worker which had a bug and then I created a new one, but this issue persists.

CF is not calling my worker at the scheduled time, for me this is a bug. If i set a specific time my worker is not called, however, when i access it by it’s url, it works.

Some details:

  • My api is working
  • When i access my worker by it’s url my api is called and a job is executed
  • My API is on production
  • My worker is on production mode as well
  • When i fire it by the CF worker editor UI my worker is called only at second click on the fire button
  • My API is responding in ~388ms
  • If i set a cron to run each 5 minutes, it will work only after 10 minutes and it will work
  • My code can be checked bellow
const API_URL="MY API URL"

addEventListener('scheduled', event => {
    event.waitUntil(triggerEvent(event.scheduledTime))
})

async function triggerEvent(scheduledTime) {
    return fetch(API_URL)
}

addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {

    const req = await fetch(API_URL)
    if (req.ok) {
        return new Response("Ok")
    }
    return new Response("Erro")
}

Thanks in advance for any help!

@user200348 May I ask have you tried deleting your code and use:

From my perspective, remove part:

addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
})

Therfore, re-edit part:

As suggested by @aloyd :

Have you checked in your Firewall Events if something is blocked maybe?

I’ll test this today, and reply back with some feedback.

Thank you for patience.

I set some crons to test. I had set the first one 10 min before it’s call time and again it appeared as executed on the UI, but actually it wasn’t executed.

I’m running my api server on vercel (next.js), so there is not firewall. I checked it but i could’t found any one.

This is my updated code without the return:

const API_URL="MY API"

addEventListener('scheduled', event => {
    event.waitUntil(fetch(API_URL)) // i'm just calling fetch
})

addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {

    const req = await fetch(API_URL)
    if (req.ok) {
        return new Response("Ok")
    }
    return new Response("Erro")
}

I really appreciate the time you are spending trying to help me!