Why the OpenTelemetry versions are pinned in lockstep¶
The problem the pins solve¶
A Go build resolves one version of each module for the whole program. A service built on
go-tool-base that also uses this module
gets one go.opentelemetry.io/otel, whichever of the two asked for the higher version.
That is usually fine, and occasionally not. The OpenTelemetry Go modules do not all share
a version line — the stable API and SDK are on v1.x while the log SDK, the log exporter
and the contrib bridges are on v0.x, and a v0.x release is only compatible with a
particular v1.x. Upgrading one module of the set on its own can produce a build that
compiles and a runtime that does not behave, or a compile error some distance from the
change that caused it.
So the versions here are pinned to match go-tool-base's, and moved together:
require (
go.opentelemetry.io/contrib/bridges/otelslog v0.19.0
go.opentelemetry.io/otel v1.44.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.20.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0
go.opentelemetry.io/otel/sdk v1.44.0
// ...
)
Renovate updates them as a group, so a bump arrives as one merge request covering the whole set rather than eleven separate ones landing in an order nobody chose.
Why gRPC and genproto are pinned as well¶
The OTLP/HTTP exporters pull gRPC in transitively, and google.golang.org/genproto has
existed both as one monolithic module and as split per-API modules. When a build graph
contains both shapes, the same Go package is reachable by two paths and the build fails
with an ambiguous import — a failure that names packages nobody in either repository
imported directly.
Pinning google.golang.org/grpc and the split genproto/googleapis/{api,rpc} modules to
go-tool-base's versions keeps one shape in the graph. The pins are documented in go.mod
next to the requires, because the reason is not inferable from the versions themselves.
What this costs you¶
A consumer cannot pick its own OTel version freely. If your service needs a newer
otel/sdk than the pin, Go's minimal version selection will give it to you — but you are
then running a combination nobody has tested, and the pin exists precisely because that
combination is where the trouble lives. The supported move is to bump go-tool-base and
this module together.
The SDK defaults documented here can move under you. Batch sizes, timeouts, the retry budget and the environment variables the SDK honours are the SDK's, not this module's. The reference pages name the version they were read from for that reason.
An urgent OTel fix is a cross-repository change. Getting one in means moving go-tool-base as well, which is deliberate — the alternative is a service resolving two different OTel generations depending on which dependency won.
What is not pinned for this reason¶
github.com/cockroachdb/errors is the module's only non-OTel runtime dependency and has
nothing to do with the lockstep. stretchr/testify is in the importable graph because
mocks/ is published as a normal package rather than a test-only one, so a consumer
wiring SettingsSource into their own service can mock it without hand-rolling a double.
The depfootprint_test.go guard is what keeps that list short: it allows
go.opentelemetry.io and fails the build on go-tool-base, Viper, Cobra, pflag, Charm and
the AWS, GCP and Azure SDKs. A regression that reintroduces framework coupling fails a
test rather than quietly enlarging every downstream binary.