nats-io/nats-server · error

error parsing 'pinned_certs' key %s does not look like lower

Error message

error parsing 'pinned_certs' key %s does not look like lower case hex-encoded sha256 of DER encoded SubjectPublicKeyInfo

What it means

validatePinnedCerts: a key in tls.pinned_certs, after lowercasing, does not match the regex ^[a-f0-9]{64}$ — i.e. it is not a 64-character lowercase hex SHA-256 fingerprint of the DER-encoded SubjectPublicKeyInfo. Typical causes: uppercase is fine (lowercased first) but wrong length, non-hex characters, 'sha256:' prefixes, or colons/spaces in the fingerprint.

Source

Thrown at server/server.go:1160

			return fmt.Errorf("pool_size cannot be negative if pinned accounts are specified")
		}
		m := make(map[string]struct{}, l)
		for _, a := range o.Cluster.PinnedAccounts {
			if _, exists := m[a]; exists {
				return fmt.Errorf("found duplicate account name %q in pinned accounts list %q", a, o.Cluster.PinnedAccounts)
			}
			m[a] = struct{}{}
		}
	}
	return nil
}

func validatePinnedCerts(pinned PinnedCertSet) error {
	re := regexp.MustCompile("^[a-f0-9]{64}$")
	for certId := range pinned {
		entry := strings.ToLower(certId)
		if !re.MatchString(entry) {
			return fmt.Errorf("error parsing 'pinned_certs' key %s does not look like lower case hex-encoded sha256 of DER encoded SubjectPublicKeyInfo", entry)
		}
	}
	return nil
}

func validateOptions(o *Options) error {
	if o.LameDuckDuration > 0 && o.LameDuckGracePeriod >= o.LameDuckDuration {
		return fmt.Errorf("lame duck grace period (%v) should be strictly lower than lame duck duration (%v)",
			o.LameDuckGracePeriod, o.LameDuckDuration)
	}
	if int64(o.MaxPayload) > o.MaxPending {
		return fmt.Errorf("max_payload (%v) cannot be higher than max_pending (%v)",
			o.MaxPayload, o.MaxPending)
	}
	if o.ServerName != _EMPTY_ && strings.Contains(o.ServerName, " ") {
		return errors.New("server name cannot contain spaces")
	}
	// Check that the trust configuration is correct.

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Provide the fingerprint as exactly 64 hex characters with no separators or prefixes
  2. Compute it via openssl x509 -pubkey | openssl pkey -pubin -outform DER | openssl dgst -sha256 and strip colons
  3. Ensure no leading 'sha256:' label or whitespace in the config entry
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/server.go:1160 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/0d318f623b1cbe37. Report an issue: GitHub.