denoland/deno · error
Failed to read env var OTEL_EXPORTER_OTLP_PROTOCOL: {}
Error message
Failed to read env var OTEL_EXPORTER_OTLP_PROTOCOL: {} What it means
Startup reads OTEL_EXPORTER_OTLP_PROTOCOL through std::env::var; only VarError::NotPresent is treated as unset (defaulting to http/protobuf). Any other VarError — in practice NotUnicode, a value with invalid UTF-8 bytes — produces this message together with the underlying error text.
Source
Thrown at ext/telemetry/lib.rs:1260
// `protocol` value is only ever the HTTP variant passed to the OTLP HTTP
// exporter builder.
let protocol_var = sys.env_var("OTEL_EXPORTER_OTLP_PROTOCOL");
let (use_console_exporter, use_grpc, protocol) = match protocol_var.as_deref()
{
Ok("console") => (true, false, Protocol::HttpBinary),
Ok("http/protobuf") | Ok("") | Err(std::env::VarError::NotPresent) => {
(false, false, Protocol::HttpBinary)
}
Ok("http/json") => (false, false, Protocol::HttpJson),
Ok("grpc") => (false, true, Protocol::HttpBinary),
Ok(protocol) => {
return Err(deno_core::anyhow::anyhow!(
"Env var OTEL_EXPORTER_OTLP_PROTOCOL specifies an unsupported protocol: {}",
protocol
));
}
Err(err) => {
return Err(deno_core::anyhow::anyhow!(
"Failed to read env var OTEL_EXPORTER_OTLP_PROTOCOL: {}",
err
));
}
};
// Define the resource attributes that will be attached to all log records.
// These attributes are sourced as follows (in order of precedence):
// * The `service.name` attribute from the `OTEL_SERVICE_NAME` env var.
// * Additional attributes from the `OTEL_RESOURCE_ATTRIBUTES` env var.
// * Default attribute values defined here.
// TODO(piscisaureus): add more default attributes (e.g. script path).
// The base resource picks up `service.name`, the `telemetry.sdk.*`
// attributes and any `OTEL_RESOURCE_ATTRIBUTES`/`OTEL_SERVICE_NAME` values.
let base_resource = Resource::builder().build();
let sdk_language = base_resource
.get(&Key::new(TELEMETRY_SDK_LANGUAGE))
.unwrap();View on GitHub (pinned to 89f33cbef2)
Solutions
- Re-export the variable with a clean ASCII/UTF-8 value: `export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf`
- Find and fix the writer that produced the non-UTF-8 value (CI secret definitions, Dockerfile ENV lines, .env encodings)
- As a stopgap, unset the variable to fall back to the default http/protobuf protocol
Example fix
# before — value inherited with non-UTF-8 bytes, startup fails deno run --unstable-otel main.ts # after — normalize to clean ASCII before starting export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf deno run --unstable-otel main.ts
Defensive patterns
Strategy: validation
Validate before calling
# normalize instead of trusting inherited environments export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf deno run --unstable-otel main.ts
Prevention
- Re-export OTEL settings in the entrypoint script rather than inheriting them
- Do not store OTLP settings in binary-encoded CI secrets
- Suspect encoding when the error text after the colon mentions invalid Unicode
When it happens
Trigger: The process environment contains OTEL_EXPORTER_OTLP_PROTOCOL with non-UTF-8 bytes: written by a buggy script, a mis-encoded CI secret, or an exec call passing raw byte environments.
Common situations: CI secret stores that saved the value with a BOM or binary encoding; container images built with broken locale handling; wrapper processes forwarding env bytes unvalidated.
Related errors
- vsock is not supported on this platform
- invalid vsock addr
- no private key found in OTEL_EXPORTER_OTLP_CLIENT_KEY file
- Env var OTEL_TRACES_SAMPLER specifies an unsupported sampler
- Env var OTEL_EXPORTER_OTLP_PROTOCOL specifies an unsupported
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/fc615971faaea356.
Report an issue: GitHub.