{"record":{"id":"a1498ab7cc5c7498","repo":"tsenart/vegeta","slug":"failed-to-register-metric-v-w","errorCode":null,"errorMessage":"failed to register metric %v: %w","messagePattern":"failed to register metric (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/prom/prom.go","lineNumber":57,"sourceCode":"\t\t\tHelp: \"Bytes sent to servers during requests\",\n\t\t}, baseLabels),\n\t\trequestFailCounter: prometheus.NewCounterVec(prometheus.CounterOpts{\n\t\t\tName: \"request_fail_count\",\n\t\t\tHelp: \"Count of failed requests\",\n\t\t}, append(baseLabels[:len(baseLabels):len(baseLabels)], \"message\")),\n\t}\n}\n\n// Register registers all Prometheus metrics in r.\nfunc (pm *Metrics) Register(r prometheus.Registerer) error {\n\tfor _, c := range []prometheus.Collector{\n\t\tpm.requestLatencyHistogram,\n\t\tpm.requestBytesInCounter,\n\t\tpm.requestBytesOutCounter,\n\t\tpm.requestFailCounter,\n\t} {\n\t\tif err := r.Register(c); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to register metric %v: %w\", c, err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Observe metrics given a vegeta.Result.\nfunc (pm *Metrics) Observe(res *vegeta.Result) {\n\tcode := strconv.FormatUint(uint64(res.Code), 10)\n\tpm.requestBytesInCounter.WithLabelValues(res.Method, res.URL, code).Add(float64(res.BytesIn))\n\tpm.requestBytesOutCounter.WithLabelValues(res.Method, res.URL, code).Add(float64(res.BytesOut))\n\tpm.requestLatencyHistogram.WithLabelValues(res.Method, res.URL, code).Observe(res.Latency.Seconds())\n\tif res.Error != \"\" {\n\t\tpm.requestFailCounter.WithLabelValues(res.Method, res.URL, code, res.Error)\n\t}\n}\n\n// NewHandler returns a new http.Handler that exposes Prometheus\n// metrics registed in r in the OpenMetrics format.","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/tsenart/vegeta/blob/cf5811269046c672a604b1eb352204d30f16ae4a/lib/prom/prom.go#L39-L75","documentation":"Returned when one of the prometheus collectors (latency histogram, bytes-in/out counters, fail counter) cannot be registered with the provided prometheus.Registerer. Prometheus rejects duplicate registrations of the same metric name, so a second Register call on the same registry fails.","triggerScenarios":"Calling prom.Registerer's Register (e.g. via attack metric registration) twice on the same prometheus.Registry, or the same registry already containing metrics with identical names.","commonSituations":"Registering vegeta attack metrics into prometheus.DefaultRegisterer in a long-running process, then re-registering (e.g. on config reload or a second attack); hot-reloading metrics without deregistering.","solutions":["Use prometheus.NewRegistry() per attack or component instead of the default global registry.","Call the Unregister (or a wrapped MustUnregister) before re-Registering the same collectors.","Guard registration with promauto or check AlreadyRegisteredError before Registering.","Upgrade vegeta if you hit duplicate-name collisions between its built-in collectors and your own."],"exampleFix":"// before\nreg := prometheus.DefaultRegisterer\nif err := prom.Register(reg); err != nil { return err }\n// after\nreg := prometheus.NewRegistry()\nif err := prom.Register(reg); err != nil { return err }","handlingStrategy":"try-catch","validationCode":"// Check for existing registration before registering vegeta metrics\nfunc safeRegister(r prometheus.Registerer, c prometheus.Collector) error {\n    if err := r.Register(c); err != nil {\n        var are prometheus.AlreadyRegisteredError\n        if errors.As(err, &are) {\n            return nil // already registered, reuse\n        }\n        return err\n    }\n    return nil\n}","typeGuard":"func isAlreadyRegistered(err error) bool {\n    var are prometheus.AlreadyRegisteredError\n    return errors.As(err, &are)\n}","tryCatchPattern":"if err := prom.Register(reg); err != nil {\n    var are prometheus.AlreadyRegisteredError\n    if errors.As(err, &are) {\n        return nil // safe to ignore: metric exists\n    }\n    return fmt.Errorf(\"metric registration failed: %w\", err)\n}","preventionTips":["Use a fresh prometheus.NewRegistry() per attack instead of DefaultRegisterer.","Unregister collectors before re-registration on config reload.","Register metrics once at startup, not per request/attack."],"tags":["go","prometheus","metrics"],"backgroundTag":"metric-already-registered","analyzedSha":"cf5811269046c672a604b1eb352204d30f16ae4a","analyzedAt":"2026-08-31T11:04:20.464Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}