cloudflare
references/workers-for-platforms/gotchas.md
.md 135 lines
Content
# Gotchas & Limits
## Common Errors
### "Worker not found"
**Cause:** Attempting to get Worker that doesn't exist in namespace
**Solution:** Catch error and return 404:
```typescript
try {
const userWorker = env.DISPATCHER.get(workerName);
return userWorker.fetch(request);
} catch (e) {
if (e.message.startsWith("Worker not found")) {
return new Response("Worker not found", { status: 404 });
}
throw e; // Re-throw unexpected errors
}
```
### "CPU time limit exceeded"
**Cause:** User Worker exceeded configured CPU time limit
**Solution:** Track violations in Analytics Engine and return 429 response; consider adjusting limits per customer tier
### "Hostname Routing Issues"
**Cause:** DNS proxy settings causing routing problems
**Solution:** Use `*/*` wildcard route which works regardless of proxy settings for orange-to-orange routing
### "Bindings Lost on Update"
**Cause:** Not using `keep_bindings` flag when updating Worker
**Solution:** Use `keep_bindings: true` in API requests to preserve existing bindings during updates
### "Tag Filtering Not Working"
**Cause:** Special characters not URL encoded in tag filters
**Solution:** URL encode tags (e.g., `tags=production%3Ayes`) and avoid special chars like `,` and `&`
### "Deploy Failures with ES Modules"
**Cause:** Incorrect upload format for ES modules
**Solution:** Use multipart form upload, specify `main_module` in metadata, and set file type to `application/javascript+module`
### "Static Asset Upload Failed"
**Cause:** Invalid hash format, expired token, or incorrect encoding
**Solution:** Hash must be first 16 bytes (32 hex chars) of SHA-256, upload within 1 hour of session creation, deploy within 1 hour of upload completion, and Base64 encode file contents
### "Outbound Worker Not Intercepting Calls"
**Cause:** Outbound Workers don't intercept Durable Object or mTLS binding fetch
**Solution:** Plan egress control accordingly; not all fetch calls are intercepted
### "TCP Socket Connection Failed"
**Cause:** Outbound Worker enabled blocks `connect()` API for TCP sockets
**Solution:** Outbound Workers only intercept `fetch()` calls; TCP socket connections unavailable when outbound configured. Remove outbound if TCP needed, or use proxy pattern.
### "API Rate Limit Exceeded"
**Cause:** Exceeded Cloudflare API rate limits (1200 requests per 5 minutes per account, 200 requests per second per IP)
**Solution:** Implement exponential backoff:
```typescript
async function deployWithBackoff(deploy: () => Promise<void>, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await deploy();
} catch (e) {
if (e.status === 429 && i < maxRetries - 1) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
continue;
}
throw e;
}
}
}
```
### "Gradual Deployment Not Supported"
**Cause:** Attempted to use gradual deployments with user Workers
**Solution:** Gradual deployments not supported for Workers in dispatch namespaces. Use all-at-once deployment with staged rollout via dispatch worker logic (feature flags, percentage-based routing).
### "Asset Session Expired"
**Cause:** Upload JWT expired (1 hour validity) or completion token expired (1 hour after upload)
**Solution:** Complete asset upload within 1 hour of session creation, and deploy Worker within 1 hour of upload completion. For large uploads, batch files or increase upload parallelism.
## Platform Limits
| Limit | Value | Notes |
|-------|-------|-------|
| Workers per namespace | Unlimited | Unlike regular Workers (500 per account) |
| Namespaces per account | Unlimited | Best practice: 1 production + 1 staging |
| Max tags per Worker | 8 | For filtering and organization |
| Worker mode | Untrusted (default) | No `request.cf` access unless trusted mode |
| Cache isolation | Per-Worker (untrusted) | Shared in trusted mode with key prefixes |
| Durable Object namespaces | Unlimited | No per-account limit for WfP |
| Gradual Deployments | Not supported | All-at-once only |
| `caches.default` | Disabled (untrusted) | Use Cache API with custom keys |
## Asset Upload Limits
| Limit | Value | Notes |
|-------|-------|-------|
| Upload session JWT validity | 1 hour | Must complete upload within this time |
| Completion token validity | 1 hour | Must deploy within this time after upload |
| Asset hash format | First 16 bytes SHA-256 | 32 hex characters |
| Base64 encoding | Required | For binary files |
## API Rate Limits
| Limit Type | Value | Scope |
|------------|-------|-------|
| Client API | 1200 requests / 5 min | Per account |
| Client API | 200 requests / sec | Per IP address |
| GraphQL | Varies by query cost | Query complexity |
See [Cloudflare API Rate Limits](https://developers.cloudflare.com/fundamentals/api/reference/limits/) for details.
## Operational Limits
| Operation | Limit | Notes |
|-----------|-------|-------|
| CPU time (custom limits) | Up to Workers plan limit | Set per-invocation in dispatch worker |
| Subrequests (custom limits) | Up to Workers plan limit | Set per-invocation in dispatch worker |
| Outbound Worker subrequests | Not intercepted for DO/mTLS | Only regular fetch() calls |
| TCP sockets with outbound | Disabled | `connect()` API unavailable |
See [README.md](./README.md), [configuration.md](./configuration.md), [api.md](./api.md), [patterns.md](./patterns.md)