{"record":{"id":"ec985d7f4e4c7a1c","repo":"denoland/deno","slug":"otel-export-timed-out-after-ms","errorCode":null,"errorMessage":"OTEL export timed out after {}ms","messagePattern":"OTEL export timed out after (.+?)ms","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ext/telemetry/lib.rs","lineNumber":919,"sourceCode":"      request: Request<Vec<u8>>,\n    ) -> Result<\n      (hyper::http::response::Parts, Option<hyper::HeaderMap>),\n      Box<dyn std::error::Error + Send + Sync>,\n    > {\n      let (parts, body) = request.into_parts();\n      let request = Request::from_parts(parts, Full::from(body));\n      let result = tokio::time::timeout(self.timeout, async {\n        let response = self.inner.request(request).await?;\n        let (parts, body) = response.into_parts();\n        let collected = http_body_util::Limited::new(body, 1024 * 1024)\n          .collect()\n          .await?;\n        let trailers = collected.trailers().cloned();\n        Ok::<_, Box<dyn std::error::Error + Send + Sync>>((parts, trailers))\n      })\n      .await\n      .map_err(|_| -> Box<dyn std::error::Error + Send + Sync> {\n        Box::new(std::io::Error::new(\n          std::io::ErrorKind::TimedOut,\n          format!(\"OTEL export timed out after {}ms\", self.timeout.as_millis()),\n        ))\n      })??;\n      Ok(result)\n    }\n  }\n\n  #[async_trait::async_trait]\n  impl opentelemetry_http::HttpClient for HyperClient {\n    async fn send_bytes(\n      &self,\n      request: Request<Bytes>,\n    ) -> Result<Response<Bytes>, HttpError> {\n      let (parts, body) = request.into_parts();\n      let request = Request::from_parts(parts, Full::new(body));\n      let response = tokio::time::timeout(self.timeout, async {\n        let response = self.inner.request(request).await?;","sourceCodeStart":901,"sourceCodeEnd":937,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/telemetry/lib.rs#L901-L937","documentation":"OTLP-over-gRPC export path in Deno's OpenTelemetry runtime: HyperClient::grpc_request wraps the whole request (connect + response + body + trailers, capped at 1 MiB) in tokio::time::timeout(self.timeout). If the collector does not complete the round trip within the budget, the future is dropped and ErrorKind::TimedOut with this message is returned. The timeout comes from OTEL_EXPORTER_OTLP_TIMEOUT in milliseconds (default 10000).","triggerScenarios":"deno run -- unstable-otel with OTEL_EXPORTER_OTLP_PROTOCOL=grpc and a collector endpoint that is unreachable, slow, or stalling (connection hang, TLS handshake slowness, collector overloaded) so the export exceeds OTEL_EXPORTER_OTLP_TIMEOUT.","commonSituations":"Remote collector behind slow links or flaky DNS; OTEL collector sidecar not yet up when the app starts; batch exports larger than the link can push in 10s; firewalls dropping packets (black hole) instead of refusing; default timeout too small for high-latency environments.","solutions":["Raise the budget: export OTEL_EXPORTER_OTLP_TIMEOUT=30000 (milliseconds).","Verify the endpoint is reachable from the app container: curl http://<collector>:4317/ and check DNS/firewall; for gRPC use port 4317.","Run/health-check a local collector sidecar and point OTEL_EXPORTER_OTLP_ENDPOINT at 127.0.0.1 so only the collector handles the slow WAN hop.","Reduce export size/frequency (OTEL_BSP_* batch settings) so a round trip fits the budget."],"exampleFix":"# before\nexport OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.example.com:4317\ndeno run --unstable-otel app.ts # exports time out after 10000ms\n\n# after\nexport OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317  # local sidecar\nexport OTEL_EXPORTER_OTLP_TIMEOUT=30000                    # 30s budget\ndeno run --unstable-otel app.ts","handlingStrategy":"retry","validationCode":"const ep = process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? \"http://127.0.0.1:4317\";\nconst ok = await fetch(ep, { signal: AbortSignal.timeout(2_000) }).then(r => true, () => false);\nif (!ok) console.warn(`OTLP collector not reachable at ${ep} — exports will time out`);","typeGuard":null,"tryCatchPattern":"try { await exportOnce(); } catch (e) { if (e instanceof Error && /OTEL export timed out/.test(e.message)) console.warn(\"OTLP gRPC export timed out — batch dropped; check collector 4317 and OTEL_EXPORTER_OTLP_TIMEOUT\"); else throw e; }","preventionTips":["Run the collector as a local sidecar (127.0.0.1:4317) and let it own WAN retries.","Set OTEL_EXPORTER_OTLP_TIMEOUT explicitly (milliseconds) for high-latency environments.","Add collector readiness checks before starting instrumented workloads.","Note that OTel batch processors drop failed batches after retries — monitor collector health, don't rely on the app."],"tags":["opentelemetry","otel","grpc","timeout","exporter","config"],"backgroundTag":"request-timeout","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}