nsqio/nsq · error

invalid E2E processing latency percentile: %v

Error message

invalid E2E processing latency percentile: %v

What it means

nsqd validates every value in the E2EProcessingLatencyPercentiles option (flag --e2e-processing-latency-percentile) at startup inside New(). Each value must be a float strictly greater than 0 and at most 1.0, because it is fed to a percentile/quantile estimator (per-channel and per-topic E2E latency histograms). Passing anything outside (0, 1.0] — such as 95 for '95 percent', 0, a negative number, or 1.01 — makes New() return this error before any listener is opened.

Source

Thrown at nsqd/nsqd.go:144

	}
	if tlsConfig == nil && opts.TLSRequired != TLSNotRequired {
		return nil, errors.New("cannot require TLS client connections without TLS key and cert")
	}
	n.tlsConfig = tlsConfig

	clientTLSConfig, err := buildClientTLSConfig(opts)
	if err != nil {
		return nil, fmt.Errorf("failed to build client TLS config - %s", err)
	}
	n.clientTLSConfig = clientTLSConfig

	if opts.AuthHTTPRequestMethod != "post" && opts.AuthHTTPRequestMethod != "get" {
		return nil, errors.New("--auth-http-request-method must be post or get")
	}

	for _, v := range opts.E2EProcessingLatencyPercentiles {
		if v <= 0 || v > 1 {
			return nil, fmt.Errorf("invalid E2E processing latency percentile: %v", v)
		}
	}

	n.logf(LOG_INFO, version.String("nsqd"))
	n.logf(LOG_INFO, "ID: %d", opts.ID)

	n.tcpServer = &tcpServer{nsqd: n}
	n.tcpListener, err = net.Listen(util.TypeOfAddr(opts.TCPAddress), opts.TCPAddress)
	if err != nil {
		return nil, fmt.Errorf("listen (%s) failed - %s", opts.TCPAddress, err)
	}
	if opts.HTTPAddress != "" {
		n.httpListener, err = net.Listen(util.TypeOfAddr(opts.HTTPAddress), opts.HTTPAddress)
		if err != nil {
			return nil, fmt.Errorf("listen (%s) failed - %s", opts.HTTPAddress, err)
		}
	}
	if n.tlsConfig != nil && opts.HTTPSAddress != "" {

View on GitHub (pinned to 85cf10c09c)

Solutions

  1. Change the flag value to a fraction in (0, 1.0]: --e2e-processing-latency-percentile=0.95 (use 1.0 for max, never 0).
  2. If a comma-separated list was used, check every element; one bad element aborts startup: '1.0,0.99,0.95'.
  3. If setting nsqd.Options in Go code, normalize before New(): divide values >1 by 100 or reject them with your own message.
  4. Re-run nsqd; validation happens before listeners bind, so no port state is affected.

Example fix

# before
nsqd --e2e-processing-latency-percentile=95

# after
nsqd --e2e-processing-latency-percentile=0.95
Defensive patterns

Strategy: validation

Validate before calling

// before calling nsqd.New(opts):
for _, p := range opts.E2EProcessingLatencyPercentiles {
    if p <= 0 || p > 1 {
        return fmt.Errorf("percentile %v must be in (0, 1.0] (use 0.95, not 95)", p)
    }
}

Type guard

func isValidPercentile(p float64) bool { return p > 0 && p <= 1.0 }

Prevention

When it happens

Trigger: Running nsqd with --e2e-processing-latency-percentile=95 (or 95.0, 0, -0.5, 1.5), or comma-separated lists like '1.0,0.99,95'. Also triggered programmatically when a caller builds nsqd.Options directly and sets E2EProcessingLatencyPercentiles to a raw percentage instead of a fraction.

Common situations: The classic mistake is giving the percentile as a whole number (95 instead of 0.95) because the flag name suggests a percentage. The help text explicitly says 'as float (0, 1.0])' but users still pass 100.0 for '100th percentile'. Misconfigured cfg files (key e2e_processing_latency_percentiles) or environment-derived values hit the same path.

Related errors


AI-assisted analysis of nsqio/nsq@85cf10c09c (2026-08-16). Data as JSON: /api/errors/05002604f58d098e. Report an issue: GitHub.