Cloudflare worker scheduling issue: API requests failing with 403 error

I’m having trouble with my Cloudflare worker. It’s supposed to fetch data from Bybit every 2 minutes. The weird thing is, when I run it manually, it works fine. But when it runs on its own, I keep getting a 403 error. I’m really confused about what’s going wrong.

Here’s a simplified version of what I’m trying to do:

export default {
  async scheduled(event, env) {
    console.log('Scheduled run started');
    await getData(env, 'auto');
  },

  async fetch(request, env) {
    console.log('Manual run started');
    const result = await getData(env, 'manual');
    return new Response(JSON.stringify(result), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
};

async function getData(env, mode) {
  const apiKey = 'your_api_key';
  const apiSecret = 'your_api_secret';
  const url = 'https://api.example.com/v1/data';
  const params = getParams(apiKey);
  const signature = await makeSignature(apiSecret, params);
  const fullUrl = `${url}?${params}&sign=${signature}`;

  try {
    const response = await fetch(fullUrl, { method: 'GET' });
    if (!response.ok) throw new Error(`HTTP error ${response.status}`);
    const data = await response.json();
    console.log(`${mode} run successful`);
    return data;
  } catch (error) {
    console.error(`${mode} run failed: ${error.message}`);
    return { error: error.message };
  }
}

Any ideas why it might be failing when run automatically?

hey there, i’ve seen this before. it’s probably a timing issue with the worker. try adding a small delay before making the API call in the scheduled function, like:

async scheduled(event, env) {
  await new Promise(resolve => setTimeout(resolve, 1000));
  await getData(env, 'auto');
}

this might help synchronize the worker’s clock with the API server. good luck!

I encountered a similar issue with Cloudflare Workers when scheduled runs failed with a 403 error. In my experience the problem often relates to authentication or timing discrepancies. I resolved mine by verifying that the API key and secret were correctly stored in the environment and not simply hardcoded. Ensuring the system clock was accurate also helped since even small time drifts can invalidate a signature. It was also useful to log the complete request URL before making the call for both manual and scheduled runs to identify any subtle differences. Lastly, considering that some APIs restrict access based on IP, checking Cloudflare’s outgoing IP ranges and using waitUntil for asynchronous operations further clarified the source of the issue.

Having dealt with similar issues, I suspect the problem might be related to how Cloudflare handles environment variables in scheduled runs. Check if your env object is properly accessible in the scheduled function. It’s also worth verifying the timestamp used for signature generation. Scheduled runs might use a different time source, causing signature mismatches. To troubleshoot, try logging the full request URL and headers for both manual and scheduled runs. Compare them to spot any discrepancies. Additionally, ensure your worker has the necessary permissions set in the Cloudflare dashboard. If the issue persists, consider implementing exponential backoff and retry logic to handle temporary API failures.