{"record":{"id":"e9389fd9ddc943c5","repo":"openzipkin/zipkin","slug":"metrics-null-e9389f","errorCode":null,"errorMessage":"metrics == null","messagePattern":"metrics == null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"zipkin-collector/pulsar/src/main/java/zipkin2/collector/pulsar/PulsarCollector.java","lineNumber":45,"sourceCode":"\n  /** Configuration including defaults needed to consume spans from a Pulsar topic. */\n  public static final class Builder extends CollectorComponent.Builder {\n    final Collector.Builder delegate = Collector.newBuilder(PulsarCollector.class);\n    CollectorMetrics metrics = CollectorMetrics.NOOP_METRICS;\n    Map<String, Object> clientProps = new HashMap<>();\n    Map<String, Object> consumerProps = new HashMap<>();\n    String topic = \"zipkin\";\n    int concurrency = 1;\n\n    @Override\n    public Builder storage(StorageComponent storage) {\n      delegate.storage(storage);\n      return this;\n    }\n\n    @Override\n    public Builder metrics(CollectorMetrics metrics) {\n      if (Objects.isNull(metrics)) throw new NullPointerException(\"metrics == null\");\n      this.metrics = metrics.forTransport(\"pulsar\");\n      this.delegate.metrics(this.metrics);\n      return this;\n    }\n\n    @Override\n    public Builder sampler(CollectorSampler sampler) {\n      this.delegate.sampler(sampler);\n      return this;\n    }\n\n    @Override\n    public PulsarCollector build() {\n      return new PulsarCollector(this);\n    }\n\n    /** Count of concurrent message consumers on the topic. Defaults to 1. */\n    public Builder concurrency(Integer concurrency) {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-collector/pulsar/src/main/java/zipkin2/collector/pulsar/PulsarCollector.java#L27-L63","documentation":"PulsarCollector.Builder.metrics(CollectorMetrics) throws NullPointerException when metrics is null (checked via Objects.isNull). The builder requires a non-null metrics implementation so per-transport metrics ('pulsar' transport) can be registered on the delegate Collector. Fail-fast at builder time.","triggerScenarios":"Calling .metrics(null), or wiring from a dependency-injection container where the CollectorMetrics bean is not defined/injectable and null is passed.","commonSituations":"Custom server integration where metrics are optional and the integrator passes a null 'when no metrics configured'.","solutions":["Pass a real CollectorMetrics instance, or the built-in no-op: CollectorMetrics.NOOP_METRICS","In DI setups, provide a default CollectorMetrics bean (NOOP) so injection never yields null","Simply omit the metrics() call — the builder already defaults to NOOP metrics"],"exampleFix":"// before\nbuilder.metrics(config.isEnabled() ? metricsImpl : null);\n\n// after\nbuilder.metrics(config.isEnabled() ? metricsImpl : CollectorMetrics.NOOP_METRICS);","handlingStrategy":"validation","validationCode":"CollectorMetrics metricsToUse = (metrics == null) ? CollectorMetrics.NOOP_METRICS : metrics;\nbuilder.metrics(metricsToUse);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use null to mean 'no metrics' — pass CollectorMetrics.NOOP_METRICS","Provide a default metrics bean in DI containers so injection cannot yield null"],"tags":["pulsar","zipkin","builder","null-check","metrics"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}