nats-io/nats-server · error
proxy timeout must be >= 0
Error message
proxy timeout must be >= 0
What it means
The leafnode remote proxy timeout is negative. validateLeafNodeProxyOptions enforces remote.Proxy.Timeout >= 0 because a negative dial/handshake timeout is meaningless and would be rejected or misbehave downstream in natsDialTimeout. This is a config-time validation error.
Source
Thrown at server/leafnode.go:412
if remote.Proxy.URL == _EMPTY_ {
return warnings, nil
}
proxyURL, err := url.Parse(remote.Proxy.URL)
if err != nil {
return warnings, fmt.Errorf("invalid proxy URL: %v", err)
}
if proxyURL.Scheme != "http" && proxyURL.Scheme != "https" {
return warnings, fmt.Errorf("proxy URL scheme must be http or https, got: %s", proxyURL.Scheme)
}
if proxyURL.Host == _EMPTY_ {
return warnings, fmt.Errorf("proxy URL must specify a host")
}
if remote.Proxy.Timeout < 0 {
return warnings, fmt.Errorf("proxy timeout must be >= 0")
}
if (remote.Proxy.Username == _EMPTY_) != (remote.Proxy.Password == _EMPTY_) {
return warnings, fmt.Errorf("proxy username and password must both be specified or both be empty")
}
if len(remote.URLs) > 0 {
hasWebSocketURL := false
hasNonWebSocketURL := false
for _, remoteURL := range remote.URLs {
if remoteURL.Scheme == wsSchemePrefix || remoteURL.Scheme == wsSchemePrefixTLS {
hasWebSocketURL = true
if (remoteURL.Scheme == wsSchemePrefixTLS) &&
remote.TLSConfig == nil && !remote.TLS {
return warnings, fmt.Errorf("proxy is configured but remote URL %s requires TLS and no TLS configuration is provided. When using proxy with TLS endpoints, ensure TLS is properly configured for the leafnode remote", remoteURL.String())
}
} else {View on GitHub (pinned to 3a66a489d2)
Solutions
- Set the proxy timeout to a non-negative duration, e.g. timeout: "5s" or omit it to use the default
- Audit config for leading minus signs on duration fields
- Clamp computed durations with a max(0, d) before assigning remote.Proxy.Timeout
Example fix
// before
proxy {
url: "http://proxy:3128"
timeout: -5s
}
// after
proxy {
url: "http://proxy:3128"
timeout: 5s
} Defensive patterns
Strategy: validation
Validate before calling
if cfg.Proxy != nil && cfg.Proxy.Timeout < 0 {
return fmt.Errorf("proxy timeout must be >= 0, got %v", cfg.Proxy.Timeout)
} Type guard
func validProxyTimeout(d time.Duration) bool { return d >= 0 } Try / catch
defer func() {
if r := recover(); r != nil { log.Fatalf("leafnode config rejected: %v", r) }
}()
// or: check the error from option parsing before starting the server Prevention
- Never write negative durations in config files
- Clamp computed durations: if d < 0 { d = 0 }
- Code-review duration fields for sign errors
When it happens
Trigger: Configuring proxy { timeout: -1 } (or any negative value) under a leafnode remote; parsing a duration that resolves negative, e.g. timeout: "-5s" or a computed negative time.Duration passed programmatically to parseRemoteLeafNodes.
Common situations: Sign typo in config (-5s instead of 5s); arithmetic on durations producing negatives; templates substituting negative defaults.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- proxy URL must specify a host
- proxy username and password must both be specified or both b
- proxy is configured but remote URL %s requires TLS and no TL
- attempted to connect to leaf node port
- remote leafnode has same cluster name
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/dc94d420ec8b282a.
Report an issue: GitHub.