Worker error codes when preventing response
When a Worker running in production has an error that prevents it from returning a response, the client receives an error page. Error code 1101: Worker threw a JavaScript exception. Error code 1102: Worker exceeded CPU time limit. Error code 1103: The owner of this worker needs to contact Cloudflare Support. Error code 1019: Worker hit loop limit. Error code 1021: Worker has requested a host it cannot access. Error code 1022: Cloudflare has failed to route the request to the Worker. Error code 1024: Worker cannot make a subrequest to a Cloudflare-owned IP address. Error code 1027: Worker exceeded free tier daily request limit. Error code 1042: Worker tried to fetch from another Worker on the same zone, which is only supported when the global_fetch_strictly_public compatibility flag is used. Error code 10162: Module has an unsupported Content-Type. Other 11xx errors generally indicate a problem with the Workers runtime itself.
Runtime errors that do not appear to end users
Runtime errors will occur within the runtime, do not throw up an error page, and are not visible to the end user. Runtime errors are detected by the user with logs. Error message 'Network connection lost' means connection failure; catch a fetch or binding invocation and retry it. Error message 'Memory limit would be exceeded before EOF' means trying to read a stream or buffer that would take you over the memory limit. Error message 'daemonDown' means a temporary problem invoking the Worker.
Example: passThroughOnException() in Module Worker
export default {
async fetch(request, env, ctx) {
ctx.passThroughOnException();
// an error here will return the origin response, as if the Worker wasn't present
return fetch(request);
},
};
This example shows how to use ctx.passThroughOnException() to forward requests to the origin if an exception is thrown during the Worker's execution.
Example: passThroughOnException() in Service Worker
addEventListener("fetch", (event) => {
event.passThroughOnException();
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
// An error here will return the origin response, as if the Worker wasn't present.
// ...
return fetch(request);
}
This example shows how to use event.passThroughOnException() in Service Workers to forward requests to the origin if an exception is thrown. Note: Service Workers are deprecated.
Client disconnect errors in metrics
The 'Client disconnected by type' chart in Workers metrics shows client disconnect errors broken down into categories: Response Stream Disconnected (connection was terminated during the deferred proxying stage of a Worker request flow; commonly appears for longer-lived connections such as WebSockets), and Cancelled (the client disconnected before the Worker completed its response).
Worker Errors metrics in dashboard
The 'Errors by invocation status' chart in Workers metrics shows errors broken down into categories: Uncaught Exception (your Worker code threw a JavaScript exception during execution), Exceeded CPU Time Limits (Worker exceeded CPU time limit or other resource constraints), Exceeded Memory (Worker exceeded the memory limit during execution), and Internal (an internal error occurred in the Workers runtime).
Go to origin on error with passThroughOnException()
By using ctx.passThroughOnException(), a Workers application can forward requests to your origin if an exception is thrown during the Worker's execution. This allows you to add logging, tracking, or other features with Workers, without degrading your application's functionality. ctx.passThroughOnException() forwards requests for unhandled exceptions in your Worker code, not for errors from the origin fetch(). When proxying requests to an origin, wrap fetch(request) in try...catch and return a 5xx response on failure. If the origin fetch() throws after consuming the request body, passThroughOnException() cannot replay the body.
Collect and persist Wasm core dumps
Configure the Wasm Coredump Service to collect coredumps from your Rust Workers applications and persist them to logs, Sentry, or R2 for analysis with wasmgdb. Refer to the Wasm Coredump Service GitHub repository and blog post for more details.
Example: external logging service with event.waitUntil() (Service Worker)
addEventListener("fetch", (event) => {
event.respondWith(handleEvent(event));
});
async function handleEvent(event) {
// ...
// Without event.waitUntil(), the `postLog` function may or may not complete.
event.waitUntil(postLog(stack));
return fetch(event.request);
}
function postLog(data) {
return fetch("https://log-service.example.com/", {
method: "POST",
body: data,
});
}
This example shows how to use event.waitUntil() in Service Workers to ensure logging completes after the response is sent to the client. Note: Service Workers are deprecated.
Example: external logging service with ctx.waitUntil() (Module Worker)
export default {
async fetch(request, env, ctx) {
function postLog(data) {
return fetch("https://log-service.example.com/", {
method: "POST",
body: data,
});
}
// Without ctx.waitUntil(), the `postLog` function may or may not complete.
ctx.waitUntil(postLog(stack));
return fetch(request);
},
};
This example shows how to use ctx.waitUntil() to ensure logging completes after the response is sent to the client.
Set up 3rd party logging service with floating promises caveat
A Worker can make HTTP requests to any HTTP service on the public Internet to collect error logs, such as using Sentry. When using an external logging strategy, remember that floating promises (promises that are neither awaited, returned, nor passed to ctx.waitUntil()) may be canceled when the Worker invocation completes. A Worker invocation has not completed while it is still streaming a response body to the client. To run logging after the response is complete, pass the request promise to ctx.waitUntil().
Debug exceptions with Workers Logs filters
Workers Logs is a powerful tool for debugging your Workers and shows all historic logs generated by your Worker, including any uncaught exceptions. To find all errors in Workers Logs, use the filter '$metadata.error EXISTS' to show all logs that have an error associated with them. You can also filter by '$workers.outcome' to find requests that resulted in an error. For example, filter by '$workers.outcome = "exception"' to find all requests that resulted in an uncaught exception.
PostHog export prerequisites
To export Cloudflare Workers telemetry to PostHog, you need an active PostHog account (free tier available), a deployed Worker, and your PostHog project API key.
Add custom attributes to PostHog logs
Custom attributes can be added to logs using standard console methods with structured data. For example:
```javascript
export default {
async fetch(request, env) {
// Basic logging
console.log("Processing request");
// Logs with additional context
console.info("User action", {
userId: "user_123",
action: "api_call",
path: new URL(request.url).pathname
});
// Error logging with details
console.error("Request failed", {
error: "Connection timeout",
retryCount: 3
});
return new Response("OK");
}
};
```
These attributes will be searchable and filterable in the PostHog logs interface.
PostHog authentication error troubleshooting
If seeing authentication errors in destination status: ensure the Authorization header value includes 'Bearer ' prefix followed by the API key; verify the API key has not been revoked or regenerated in PostHog; or alternatively pass the token as a query parameter using 'https://us.i.posthog.com/i/v1/logs?token=<your-project-api-key>' as the endpoint.
Troubleshoot PostHog logs not appearing
If logs are not appearing in PostHog, verify: the API key is your project API key (starts with 'phc_'), not a personal API key; you are using the correct regional endpoint (US or EU) matching your PostHog instance; the destination status in Cloudflare dashboard shows a recent successful delivery; and check if a sampling rate is configured that may prevent all logs from being sent.
Filter PostHog logs by attributes
Logs exported to PostHog can be filtered by severity level (trace, debug, info, warn, error, fatal), time range, custom attributes added to log entries, and keywords in log messages.
PostHog logs appear after deployment delay
It may take a few minutes after deploying a Worker for logs to appear in PostHog.
Configure PostHog destination in Cloudflare dashboard
To create a PostHog logs destination: navigate to Workers Observability in the Cloudflare dashboard, click 'Add destination', set Destination Name to a descriptive name like 'posthog-logs', select Destination Type as 'Logs', enter the OTLP Endpoint (the PostHog logs endpoint for your region), and add a Custom Header with name 'Authorization' and value 'Bearer <your-project-api-key>'.
PostHog export supports logs only
Cloudflare Workers Observability currently supports exporting logs to PostHog. Exporting traces to PostHog is not currently supported.
PostHog regional log endpoints
PostHog has two regional endpoints for logs: US endpoint at 'https://us.i.posthog.com/i/v1/logs' (default) and EU endpoint at 'https://eu.i.posthog.com/i/v1/logs'. The region can be found in PostHog project settings or by checking the URL when logged in (either us.posthog.com or eu.posthog.com).
PostHog project API key format
PostHog project API keys start with the prefix 'phc_' followed by alphanumeric characters. The format is similar to 'phc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'. This is the same key used for capturing events and exceptions.
OpenTelemetry known limitations
Exporting Worker infrastructure metrics and custom metrics via OpenTelemetry is not currently available. Some observability providers are still rolling out OTLP endpoint support and may not yet be available.
persist field and dashboard storage billing
By default, the persist field is true, which means logs and traces are both exported to your destination and stored in the Cloudflare dashboard. Dashboard storage is billed separately from the Workers Paid plan. Set persist to false if you only need data in your external destination to avoid additional storage costs.
Destination status indicators
After creating a destination, the Cloudflare dashboard displays a status indicator showing: 'Last: n minutes ago' if data was recently delivered successfully; 'Never run' if no data has been delivered (check if your Worker is receiving traffic or review sampling rates); 'Error' if an error occurred while attempting delivery (verify OTLP endpoint URL is correct and check that authentication headers are valid).
Authentication for OpenTelemetry destinations
Most OpenTelemetry providers require authentication headers. Refer to your provider's documentation for specific authentication requirements. Custom headers can be configured when creating a destination in the Cloudflare dashboard.
Destination configuration in Cloudflare dashboard
To create a destination in the Cloudflare dashboard Workers Observability section, configure: Destination Name (a descriptive name like 'Grafana-tracing' or 'Honeycomb-Logs'), Destination Type (choose between 'Traces' or 'Logs'), OTLP Endpoint (the URL where your observability platform accepts OTLP data), and Custom Headers (optional, for authentication headers or provider-required headers).
OTLP binary format not supported
Cloudflare does not support the Binary format (Binary Protobuf Encoding) for OTLP ingest.
OpenTelemetry destinations endpoint table
The following OTLP endpoint formats are available for popular observability providers:
| Provider | Traces Endpoint | Logs Endpoint |
|----------|-----------------|---------------|
| Honeycomb | https://api.honeycomb.io/v1/traces | https://api.honeycomb.io/v1/logs |
| Grafana Cloud | https://otlp-gateway-{region}.grafana.net/otlp/v1/traces | https://otlp-gateway-{region}.grafana.net/otlp/v1/logs |
| Firetiger | https://ingest.cloud.firetiger.com/v1/traces | https://ingest.cloud.firetiger.com/v1/logs |
| Axiom | https://api.axiom.co/v1/traces | https://api.axiom.co/v1/logs |
| Sentry | https://{HOST}/api/{PROJECT_ID}/integration/otlp/v1/traces | https://{HOST}/api/{PROJECT_ID}/integration/otlp/v1/logs |
| PostHog | Not supported | https://{REGION}.i.posthog.com/i/v1/logs |
| Datadog | https://otlp.{SITE}.datadoghq.com/v1/traces | https://otlp.{SITE}.datadoghq.com/v1/logs |
| New Relic | https://otlp.nr-data.net/v1/traces | https://otlp.nr-data.net/v1/logs |
| Splunk Observability | https://ingest.{REALM}.signalfx.com/v2/trace/otlp | N/A |
| Splunk Platform | http://splunk.internal:4318/v1/traces | http://splunk.internal:4318/v1/logs |
Supported OpenTelemetry telemetry types
Cloudflare Workers supports exporting traces (showing request flows through your Worker and connected services) and logs (including console.log() output and system-generated logs). Exporting Worker metrics and custom metrics is not yet supported.
OpenTelemetry export from Workers
Workers supports exporting OpenTelemetry-compliant traces and logs to any destination with an OTLP endpoint. Supported destinations include Honeycomb, Grafana Cloud, Axiom, and Sentry.
Query Builder for telemetry data
The Query Builder helps write structured queries to investigate and visualize telemetry data. It supports building queries with filters, aggregations, and groupings to analyze logs and identify patterns.
Debugging tools for Workers
Workers provides multiple debugging tools: Errors and exceptions documentation for understanding Workers error codes and common issues; Source maps and stack traces for readable stack traces mapped to original source code; Chrome DevTools for breakpoints, CPU profiling, and memory debugging during local development; and Local observability for capturing traces, spans, and logs from Workers locally.
Observability tools overview
Cloudflare Workers provides comprehensive observability tools including logs, traces, metrics, and analytics. Logs are available through Workers Logs (stored in Cloudflare dashboard), Real-time logs (near real-time access), Tail Workers (custom filtering and transformation), and Workers Logpush (export to R2, S3, or logging providers). Traces provide end-to-end visibility into requests through Workers and connected services with automatic instrumentation for fetch calls, binding operations (KV, R2, Durable Objects), and handler invocations. Metrics and analytics monitor Worker health with built-in metrics including request counts, error rates, CPU time, wall time, and execution duration, viewable per Worker or aggregated across all Workers on a zone.
Sentry data propagation delay after deployment
It may take a few minutes after Worker deployment for telemetry data to appear in Sentry.
Sentry OTLP endpoints for traces and logs
Sentry provides separate OTLP endpoints for traces and logs. Traces endpoint: https://{HOST}/api/{PROJECT_ID}/integration/otlp/v1/traces. Logs endpoint: https://{HOST}/api/{PROJECT_ID}/integration/otlp/v1/logs. These endpoints are found in project settings under Settings > Projects, select your project, then go to Client Keys (DSN) sub-page under SDK Setup heading.
Configure Sentry logs destination in Cloudflare dashboard
In the Cloudflare dashboard Workers Observability section, add a logs destination with: Destination Name (e.g., 'sentry-logs'), Destination Type set to 'Logs', OTLP Endpoint pointing to your Sentry logs endpoint, and Custom Headers with the x-sentry-auth authentication header.
Sentry authentication header for OTLP
To authenticate with Sentry's OTLP endpoints, add a custom header named 'x-sentry-auth' with value 'sentry sentry_key={SENTRY_PUBLIC_KEY}' where {SENTRY_PUBLIC_KEY} is your Sentry project's public key.
Real-time logs for near real-time visibility
Real-time logs provide access to log events in near real-time, giving immediate feedback and visibility into the health of your Cloudflare Worker.
Workers Logs feature for dashboard analysis
Workers Logs allows developers to automatically ingest, filter, and analyze logs emitted from Cloudflare Workers in the Cloudflare dashboard.
Workers Logpush for log export
Workers Logpush enables sending Workers Trace Event Logs to a supported destination. Logpush includes metadata about requests and responses, unstructured console.log() messages, and any uncaught exceptions.
Tail Workers for custom telemetry filtering
Tail Workers allow developers to apply custom filtering, sampling, and transformation logic to telemetry data. This feature is currently in Beta.
Durable Objects logs appear in dashboard
Logs from any Durable Objects that a Worker is using will show up in the dashboard's real-time logs.
Real-time logs do not persist
Real-time logs does not store Workers Logs. To store logs persistently, use Workers Logs instead.
Real-time logs sampling mode
If a Worker has a high volume of traffic, real-time logs might enter sampling mode. This causes some messages to be dropped and a warning to appear in the logs. Filtering real-time logs in the dashboard or using wrangler tail can help mitigate messages from being dropped.
View real-time logs in dashboard
To view real-time logs in the Cloudflare dashboard: navigate to the Workers & Pages page, select your Worker in Overview, select the Logs tab, and then select Live in the right-hand navigation bar.
Real-time logs not available on China Network
Real-time logs are not available for zones on the Cloudflare China Network.
Real-time logs overview and capabilities
Real-time logs provide access to all log events in near real-time for log events happening globally. They capture invocation logs, custom logs, errors, and uncaught exceptions. Real-time logs are helpful for immediate feedback, such as the status of a new deployment. For high-traffic applications, real-time logs may enter sampling mode, which means some messages will be dropped and a warning will appear in the logs.
Enable Logpush via multipart script upload API
To enable Logpush using the multipart script upload API, include logpush: true in the metadata parameter:
```bash
curl --request PUT \
"https://api.cloudflare.com/client/v4/accounts/{account_id}/workers/scripts/{script_name}" \
--header "Authorization: Bearer <API_TOKEN>" \
--form 'metadata={"main_module": "my-worker.js", "logpush": true}' \
--form '"my-worker.js"=@./my-worker.js;type=application/javascript+module'
```
Logpush roles with configuration access
Roles with Logpush configuration access include Super Administrators, Administrators, and the Log Share role. These roles have full access to Logpush. Roles with Logpush configuration access are different than Workers permissions.
OpenTelemetry export preferred over Logpush for new integrations
For new integrations, OpenTelemetry export is recommended instead of Logpush. OpenTelemetry export supports both traces and logs, can be configured with persist: false to avoid storing logs and traces in Cloudflare, and works with any OTLP-compatible destination.
Logpush contents: requests, responses, logs and exceptions
Workers Trace Events Logpush includes metadata about requests and responses, unstructured console.log() messages, and any uncaught exceptions.
Workers Trace Event Logs Logpush availability
Workers Trace Events Logpush is available on the Workers Paid plan. It is not available for zones on the Cloudflare China Network.
API token for Logpush access
You can create an API token scoped at the Account level with Logs Edit permissions to configure a Logpush job if your role does not have Logpush configuration access.
Create Logpush job via cURL to send to R2
Example cURL request to create a Logpush job sending Workers logs to R2:
```bash
curl "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/logpush/jobs" \
--header 'X-Auth-Key: <API_KEY>' \
--header 'X-Auth-Email: <EMAIL>' \
--header 'Content-Type: application/json' \
--data '{
"name": "workers-logpush",
"output_options": {
"field_names": ["Event", "EventTimestampMs", "Outcome", "Exceptions", "Logs", "ScriptName"],
},
"destination_conf": "r2://<BUCKET_PATH>/{DATE}?account-id=<ACCOUNT_ID>&access-key-id=<R2_ACCESS_KEY_ID>&secret-access-key=<R2_SECRET_ACCESS_KEY>",
"dataset": "workers_trace_events",
"enabled": true
}' | jq .
```
Logpush filtering and sampling
In Logpush, you can configure filters and a sampling rate to control the volume of data sent to your configured destination. For example, to receive logs only for requests that did not result in an exception, add a filter property: {"where": {"key":"Outcome","operator":"!eq","value":"exception"}}
Tail Worker use cases
Tail Workers can process logs for alerts, debugging, or analytics. You can filter, change the format of the data, and send events to any HTTP endpoint. For quick debugging, Tail Workers can be used to send logs to KV or any database.
Tail Worker invocation timing and scope
A Tail Worker is automatically invoked after the invocation of a producer Worker finishes executing. It captures events throughout the request lifecycle, including potential sub-requests via Service Bindings and Dynamic Dispatch.
Tail Worker definition and availability
A Tail Worker receives information about the execution of other Workers (known as producer Workers), such as HTTP statuses, data passed to console.log(), or uncaught exceptions. Tail Workers are available to all customers on the Workers Paid and Enterprise tiers. Tail Workers are billed by CPU time, not by the number of requests.
Tail Worker vs OpenTelemetry export
If exporting logs and errors to observability tools like Sentry, Grafana, or Honeycomb, you may not need to use Tail Workers. Instead, you can configure a Worker to export OpenTelemetry (OTEL) format logs and traces to these tools. With OTEL, logs and traces are sent in batches to your destination rather than sent after each invocation. Tail Workers should be considered the advanced-mode option for custom requirements not built into the Workers observability platform.