quarkusio/quarkus · error · IllegalStateException

No Clock bean found

Error message

No Clock bean found

What it means

The Quarkus OpenTelemetry extension requires a CDI bean of type io.opentelemetry.api.common/clock (io.opentelemetry.sdk.common.Clock) when metrics are enabled, to back the SdkMeterProvider. When the metrics module is active and metrics.enabled is true but no Clock bean is resolvable from the container, the builder throws IllegalStateException('No Clock bean found'). The extension normally provides this bean itself, so losing it signals a broken/absent OpenTelemetry metrics wiring.

Source

Thrown at extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/AutoConfiguredOpenTelemetrySdkBuilderCustomizer.java:312

            this.oTelBuildConfig = oTelBuildConfig;
            this.clock = clock;
            this.managedExecutor = managedExecutor;
            this.oTelRuntimeConfig = runtimeConfig;
        }

        @Override
        public void customize(AutoConfiguredOpenTelemetrySdkBuilder builder) {
            AtomicReference<MetricExporter> metricExporterRef = new AtomicReference<>();
            builder.addMeterProviderCustomizer(
                    new BiFunction<SdkMeterProviderBuilder, ConfigProperties, SdkMeterProviderBuilder>() {
                        @Override
                        public SdkMeterProviderBuilder apply(SdkMeterProviderBuilder meterProviderBuilder,
                                ConfigProperties configProperties) {

                            if (oTelBuildConfig.metrics().enabled().orElse(TRUE)) {

                                if (clock.isUnsatisfied()) {
                                    throw new IllegalStateException("No Clock bean found");
                                }
                                meterProviderBuilder.setClock(clock.get());
                            } else {
                                // disable batch exporter metrics if metrics disabled
                                // In the future we can inject scopes here.
                                Set<String> dropInstrumentationScopes = Set.of(
                                        "io.opentelemetry.sdk.trace",
                                        "io.opentelemetry.sdk.logs",
                                        "io.opentelemetry.sdk.metrics");
                                for (String target : dropInstrumentationScopes) {
                                    SdkMeterProviderUtil.addMeterConfiguratorCondition(
                                            meterProviderBuilder,
                                            nameEquals(target),
                                            MeterConfig.disabled());
                                }
                            }
                            return meterProviderBuilder;
                        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure the Quarkus OpenTelemetry extension's default beans are not excluded: remove any quarkus.otel.* exclusion or custom @Alternative that removes the default Clock producer
  2. If providing a custom Clock, register it as a CDI bean: @Produces @Singleton Clock clock() { return System::nanoTime; } (proper SdkClock/SdkMillisClock)
  3. Check that quarkus-opentelemetry runtime module is fully on the classpath and version-aligned; do a clean rebuild
  4. If metrics are not intended, set quarkus.otel.metrics.enabled=false

Example fix

// before
@ApplicationScoped
class MyOtelConfig {
   // no Clock bean produced
}
// after
@ApplicationScoped
class MyOtelConfig {
   @Produces
   @Singleton
   Clock clock() {
      return io.opentelemetry.sdk.metrics.SdkMeterProvider.builder().getClock(); // or a custom Clock impl
   }
}
Defensive patterns

Strategy: validation

Validate before calling

// verify a Clock bean exists before metrics-dependent initialization
static void requireClockBean(BeanManager bm) {
    if (bm.getBeans(Clock.class).isEmpty()) {
        throw new IllegalStateException(
            "Provide a CDI bean of io.opentelemetry.sdk.common.Clock or disable metrics");
    }
}

Type guard

static boolean hasClockBean(BeanManager bm) {
    return !bm.getBeans(Clock.class).isEmpty();
}

Try / catch

try {
    otelInitialization();
} catch (IllegalStateException e) {
    if ("No Clock bean found".equals(e.getMessage())) {
        // register fallback clock or disable metrics and retry init
    }
    throw e;
}

Prevention

When it happens

Trigger: Application starts with quarkus.otel.metrics.enabled=true (or default) while no Clock bean is registered in the CDI container — e.g. custom OpenTelemetry configuration overriding the extension's beans, or the clock supplier's isUnsatisfied() returning true because the OpenTelemetry support bean was excluded or its producer removed.

Common situations: Users supplying their own custom OpenTelemetrySdk builder customization, disabling Quarkus's default OpenTelemetry beans via @ExcludeInterceptor/property (quarkus.otel.enabled=false interplay), or replacing the recorded clock bean; also broken extension versions where the metrics clock producer was removed.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/c07d422aa2260208. Report an issue: GitHub.