denoland/deno · error

Env var OTEL_TRACES_SAMPLER specifies an unsupported sampler

Error message

Env var OTEL_TRACES_SAMPLER specifies an unsupported sampler: {}

What it means

With OTEL enabled, OTEL_TRACES_SAMPLER selects the span sampler. Accepted values are exactly always_on, always_off, traceidratio, parentbased_always_on, parentbased_always_off and parentbased_traceidratio; the value is trimmed and empty falls back to the default always-on sampler. Any other string aborts telemetry init.

Source

Thrown at ext/telemetry/lib.rs:1175

      },
      "traceidratio" => Sampler {
        parent_based: false,
        root: RootSampler::TraceIdRatio(ratio()),
      },
      "parentbased_always_on" => Sampler {
        parent_based: true,
        root: RootSampler::AlwaysOn,
      },
      "parentbased_always_off" => Sampler {
        parent_based: true,
        root: RootSampler::AlwaysOff,
      },
      "parentbased_traceidratio" => Sampler {
        parent_based: true,
        root: RootSampler::TraceIdRatio(ratio()),
      },
      other => {
        return Err(deno_core::anyhow::anyhow!(
          "Env var OTEL_TRACES_SAMPLER specifies an unsupported sampler: {}",
          other
        ));
      }
    };
    Ok(sampler)
  }

  /// Returns whether a span with the given `trace_id` should be sampled
  /// (recorded and exported), given its `parent` span context if any.
  fn should_sample(
    &self,
    parent: Option<&SpanContext>,
    trace_id: TraceId,
  ) -> bool {
    let parent_decision = parent.and_then(|parent| {
      (self.parent_based && parent.is_valid()).then(|| parent.is_sampled())
    });

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Use one of the six exact lowercase names, e.g. `OTEL_TRACES_SAMPLER=parentbased_traceidratio`
  2. For ratio samplers set the probability via `OTEL_TRACES_SAMPLER_ARG=0.25` (parsed as f64, clamped to [0,1], default 1.0)
  3. Unset the variable to keep the default always-on sampling

Example fix

# before — casing/separator mismatch
export OTEL_TRACES_SAMPLER=ParentBased_AlwaysOn

# after — exact name; ratio goes in the ARG variable
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.25
Defensive patterns

Strategy: validation

Validate before calling

case "${OTEL_TRACES_SAMPLER:-}" in
  ""|always_on|always_off|traceidratio|parentbased_always_on|parentbased_always_off|parentbased_traceidratio) ;;
  *) echo "unsupported OTEL_TRACES_SAMPLER: '$OTEL_TRACES_SAMPLER'"; exit 1;;
esac
deno run --unstable-otel main.ts

Type guard

const SAMPLERS = new Set([
  "always_on",
  "always_off",
  "traceidratio",
  "parentbased_always_on",
  "parentbased_always_off",
  "parentbased_traceidratio",
] as const);
type SamplerName = (typeof SAMPLERS) extends Set<infer T> ? T : never;
const isSamplerName = (v: string): v is SamplerName => (SAMPLERS as Set<string>).has(v);

Prevention

When it happens

Trigger: Setting OTEL_TRACES_SAMPLER to a value outside the six supported names — different casing (`AlwaysOn`), separator variants (`parent-based_always_on`, `parentbased_traceid_ratio`), or sampler names from other OTel SDKs.

Common situations: Porting OTel config between SDKs that spell sampler names differently; typos; assuming the ratio can be appended to the name instead of using the ARG variable.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/a8912e8eb4e57a25. Report an issue: GitHub.