OTCA common mistakes
OTCA · Understand the traps and how to avoid them.
Treating traces, metrics, logs, and baggage as interchangeable or assuming a span automatically produces a metric or log record, then answering questions as if enabling tracing also enables metrics.
Candidates learn the SDK as one blob and don't internalize that each signal has its own provider, exporter, and pipeline; baggage in particular is context-only and is never exported as a signal.
What to do instead
Build a mental table: for each signal, what creates it (Tracer/Meter/Logger), which provider owns it, what exporter sends it, and whether it is sampled. Explicitly note baggage is propagated, not exported.
Confusing the API, the SDK, and the OTLP protocol - e.g., saying application code calls the Collector directly, or that the API includes batching and sampling logic.
Instrumentation libraries and the SDK are usually preconfigured in examples, so the boundary between the no-op API and the configurable SDK is invisible in practice.
What to do instead
Memorize the layering: API defines interfaces and no-ops; SDK implements providers, processors, samplers, exporters; OTLP is the wire protocol used by exporters. Application code only touches the API.
Assuming span context propagates automatically across process or thread boundaries (HTTP clients, message queues, async executors) without injecting and extracting it.
In-process parent-child relationships are automatic via the active context, which creates a false expectation that distributed propagation is also automatic.
What to do instead
For every cross-process hop, identify where injection happens (client/interceptor) and where extraction happens (server/interceptor). Check that a propagator is registered and that async work carries the context explicitly.
Mixing up W3C Trace Context and Baggage headers, or assuming baggage values are automatically attached to spans and exported.
Both travel in HTTP headers and are configured together in the propagator list, so they blur together.
What to do instead
Remember traceparent/tracestate carry trace identity; baggage carries arbitrary key-values and must be explicitly read from context and added to spans or logs if you want them recorded.
Misconfiguring the Collector pipeline - putting the wrong signal's receiver or exporter into a pipeline, or forgetting that a component must be declared in service.pipelines to take effect.
Collector config has separate top-level component sections and a service section; defining a receiver without wiring it into a pipeline is silently inert.
What to do instead
Read configs bottom-up: components defined, then service.pipelines. lists receivers, processors, exporters. Verify the signal name in the pipeline matches the component type.
Confusing processors that transform data (attributes, batch, memory_limiter, filter) with connectors and extensions, or placing batch before memory_limiter.
All appear under the same config style and candidates memorize names without their ordering semantics.
What to do instead
Learn the recommended processor order (memory_limiter first, batch last before exporters) and what each does. Extensions are service-level (health_check, pprof), connectors join two pipelines.
Assuming head sampling decisions are made in the Collector, or that a sampler can be changed after a span starts.
Sampling is discussed alongside Collector configuration, so candidates conflate SDK-side head sampling with Collector-side tail sampling.
What to do instead
Head sampling is an SDK decision made at span start and is final; tail sampling is a Collector processor that buffers complete traces and decides later. Know which component owns each.
Treating automatic instrumentation as covering everything, or expecting it to instrument custom business logic and internal function calls.
Auto-instrumentation impressively captures HTTP, DB, and messaging, so candidates overestimate its reach.
What to do instead
State the boundary: auto-instrumentation covers known libraries and frameworks; custom spans, attributes, and business events require manual instrumentation via the API.
Ignoring semantic conventions - inventing attribute names, using the wrong attribute type, or putting high-cardinality values in metric attributes.
Custom naming feels natural and the spec's exact keys (e.g., http.request.method vs http.method) look arbitrary.
What to do instead
Use the current semantic convention keys and types verbatim, and keep metric dimensions bounded; move unbounded values to span attributes or logs.
Debugging missing telemetry by changing application code first, instead of checking the export path, endpoint, authentication, and Collector logs/health.
Silent export failures (wrong endpoint, TLS/auth errors, dropped batches) look identical to instrumentation bugs from the app side.
What to do instead
Triage in order: is data produced (SDK debug logging), is it exported (exporter errors), is it received (Collector logs, zpages/health_check), is it stored/visible in the backend. Fix the earliest failing link.