nats-io/nats-server · error
leafnode: %v
Error message
leafnode: %v
What it means
This is a wrapping error emitted by validateLeafNode when validatePinnedCerts fails for the leafnode's TLSPinnedCerts. The original problem (an invalid pinned cert spec, e.g. malformed fingerprint or pubkey) is formatted as "leafnode: %v". It surfaces during Options validation whenever leaf node TLS pinned certificates are configured incorrectly.
Source
Thrown at server/leafnode.go:352
if err := checkLeafMinVersionConfig(mv); err != nil {
return err
}
}
// The checks below will be done only when detecting that we are configured
// with gateways. So if an option validation needs to be done regardless,
// it MUST be done before this point!
if o.Gateway.Name == _EMPTY_ && o.Gateway.Port == 0 {
return nil
}
// If we are here we have both leaf nodes and gateways defined, make sure there
// is a system account defined.
if o.SystemAccount == _EMPTY_ {
return fmt.Errorf("leaf nodes and gateways (both being defined) require a system account to also be configured")
}
if err := validatePinnedCerts(o.LeafNode.TLSPinnedCerts); err != nil {
return fmt.Errorf("leafnode: %v", err)
}
return nil
}
func checkLeafMinVersionConfig(mv string) error {
if ok, err := versionAtLeastCheckError(mv, 2, 8, 0); !ok || err != nil {
if err != nil {
return fmt.Errorf("invalid leafnode's minimum version: %v", err)
} else {
return fmt.Errorf("the minimum version should be at least 2.8.0")
}
}
return nil
}
// Used to validate user names in LeafNode configuration.
// - rejects mix of single and multiple users.
// - rejects duplicate user names.View on GitHub (pinned to 3a66a489d2)
Solutions
- Read the wrapped inner error (the %v) to see why the pinned cert is invalid
- Re-generate the pinned cert value, e.g. sha256 fingerprint of the peer cert, and paste it exactly (lowercase hex, no colons)
- Remove the tls_pinned_certs entries if pinning is not required
Defensive patterns
Strategy: validation
Validate before calling
for _, c := range opts.LeafNode.TLSPinnedCerts {
if _, err := hex.DecodeString(c); err != nil || len(c) != 64 {
return fmt.Errorf("bad pinned cert %q: %v", c, err)
}
} Prevention
- Store fingerprints as lowercase hex without separators
- Generate pinned cert values with `openssl x509 -fingerprint -sha256` and copy programmatically
- Test pinned-cert configs with `nats-server -t` before rollout
When it happens
Trigger: validateOptions -> validateLeafNode runs and validatePinnedCerts(o.LeafNode.TLSPinnedCerts) returns an error, i.e. the leafnode block contains tls_pinned_certs entries that fail validation (bad hex digest, unsupported format, empty entries).
Common situations: Operators hand-copy SHA-256 fingerprints with typos/extra characters, or use a cert format not supported by the pinned-cert validator, when hardening leaf node TLS connections.
Related errors
- remote leaf node URL %q cannot be used in FIPS-140 mode when
- leaf nodes and gateways (both being defined) require a syste
- invalid leafnode's minimum version: %v
- the minimum version should be at least 2.8.0
- can not have a single user/pass and a users array
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/640fd0e5e7eb4283.
Report an issue: GitHub.