Introduction
Cloudflare Workers run JavaScript at Cloudflare's edge, but script errors, resource limits, and deployment issues can cause failures. Workers have strict constraints: 10ms CPU time for free plans (50ms for paid), 128MB memory limit, and specific API restrictions. When a Worker fails, you may see 5xx errors, timeout messages, or unexpected behavior. Debugging requires checking logs, understanding limits, and testing locally before deployment.
Symptoms
- Error 1101: Worker threw exception
- Error 522/524: Worker timeout contacting origin
- Worker script not executing or returning unexpected results
- "Worker exceeded resource limits" error
- Deployment fails with validation errors
- Worker runs but modifies response incorrectly
- Requests hang or return empty responses
Common Causes
- JavaScript exception in Worker script (undefined variable, syntax error)
- Worker CPU time limit exceeded (free: 10ms, paid: 50ms, unlimited: 30s)
- Memory limit exceeded (128MB maximum)
- Missing event handler or incorrect fetch response
- Infinite loop or blocking synchronous code
- Incorrect Workers KV or Durable Objects usage
- Invalid wrangler.toml configuration
- Subrequest timeout waiting for origin or external API
Step-by-Step Fix
- 1.Check Worker logs for error details:
```bash # View real-time Worker logs wrangler tail
# Or via dashboard: Workers & Pages > your-worker > Logs
# Look for exception messages and stack traces ```
- 1.Test Worker locally before deployment:
```bash # Run Worker locally with wrangler wrangler dev
# Test with curl curl http://localhost:8787/
# Debug with console.log (visible in wrangler dev output) ```
- 1.Handle exceptions properly in Worker:
```javascript // Good: Catch all errors export default { async fetch(request, env, ctx) { try { // Your Worker logic return new Response("Hello World"); } catch (error) { // Log error for debugging console.error("Worker error:", error.message);
// Return proper error response
return new Response(Error: ${error.message}, {
status: 500,
headers: { "Content-Type": "text/plain" }
});
}
}
};
```
- 1.Fix common JavaScript errors:
```javascript // Check for common mistakes:
// Undefined variable - always declare let result = someFunction(); // Define function first
// Missing await for async operations const response = await fetch(url); // Must await
// Incorrect Response construction return new Response(body, { status: 200 }); // Status in options object
// Accessing undefined properties const value = obj?.property || "default"; // Use optional chaining ```
- 1.Optimize for CPU time limits:
```javascript // Reduce CPU usage:
// Use streaming instead of buffering entire body const stream = request.body; return new Response(stream);
// Avoid heavy computation in Worker // Move to Durable Objects or external service
// Cache expensive operations const cached = await caches.default.match(request); if (cached) return cached; ```
- 1.Handle subrequest timeouts:
```javascript // Set timeout for fetch requests async function fetchWithTimeout(url, timeoutMs = 5000) { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), timeoutMs);
try { const response = await fetch(url, { signal: controller.signal }); clearTimeout(timeout); return response; } catch (error) { clearTimeout(timeout); if (error.name === 'AbortError') { return new Response('Request timeout', { status: 504 }); } throw error; } } ```
- 1.Check memory usage:
```javascript // Avoid memory-intensive operations:
// Don't load large files into memory // Use streaming instead const response = await fetch(url); return new Response(response.body); // Stream body directly
// Don't accumulate large arrays // Process in chunks or use generators
// Clear unnecessary references let largeData = null; // After use, allow GC ```
- 1.Validate wrangler.toml configuration:
```toml # Check wrangler.toml for errors name = "my-worker" main = "src/index.js" compatibility_date = "2024-01-01"
# For Workers with KV [[kv_namespaces]] binding = "KV" id = "your_kv_namespace_id"
# For Workers with Durable Objects [[durable_objects.bindings]] name = "MY_DO" class_name = "MyDurableObject"
# Check script path matches actual file location ```
- 1.Deploy and verify:
```bash # Deploy Worker wrangler deploy
# Verify deployment wrangler deployments list
# Test deployed Worker curl https://your-worker.your-subdomain.workers.dev/
# Or test on your zone curl https://yourdomain.com/ -H "Host: yourdomain.com" ```
- 1.Use Durable Objects for stateful operations:
```javascript // For operations needing more CPU time or state export class MyDurableObject { constructor(state, env) { this.state = state; }
async fetch(request) { // Durable Objects have 30s CPU limit (unlimited plan) // Can maintain state between requests const storage = this.state.storage; await storage.put("key", "value"); return new Response("Stored"); } } ```
Verification
After applying fixes:
- 1.
wrangler tailshows no exceptions or errors - 2.
curlto Worker endpoint returns expected response - 3.Worker completes within CPU time limits
- 4.Memory usage stays under 128MB
- 5.Subrequests complete without timeout
- 6.Deployment succeeds without validation errors