nats-io/nats-server · error

gateway %q: %v

Error message

gateway %q: %v

What it means

Wraps a validatePinnedCerts failure for the gateway's TLSPinnedCerts, prefixed with the gateway's name. Pinned cert checks reject entries that are neither valid hex-encoded SHA-256 fingerprints nor valid base64 values, so gateway TLS pinning configuration is invalid.

Source

Thrown at server/gateway.go:328

	if o.Gateway.Name == _EMPTY_ {
		return errors.New("gateway has no name")
	}
	if strings.Contains(o.Gateway.Name, " ") {
		return ErrGatewayNameHasSpaces
	}
	if o.Gateway.Port == 0 {
		return fmt.Errorf("gateway %q has no port specified (select -1 for random port)", o.Gateway.Name)
	}
	for i, g := range o.Gateway.Gateways {
		if g.Name == _EMPTY_ {
			return fmt.Errorf("gateway in the list %d has no name", i)
		}
		if len(g.URLs) == 0 {
			return fmt.Errorf("gateway %q has no URL", g.Name)
		}
	}
	if err := validatePinnedCerts(o.Gateway.TLSPinnedCerts); err != nil {
		return fmt.Errorf("gateway %q: %v", o.Gateway.Name, err)
	}
	return nil
}

// Computes a hash of 6 characters for the name.
// This will be used for routing of replies.
func getGWHash(name string) []byte {
	return []byte(getHashSize(name, gwHashLen))
}

func getOldHash(name string) []byte {
	sha := sha256.New()
	sha.Write([]byte(name))
	fullHash := []byte(fmt.Sprintf("%x", sha.Sum(nil)))
	return fullHash[:4]
}

// Initialize the s.gateway structure. We do this even if the server

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Replace each pinned_certs entry with the full hex-encoded SHA-256 fingerprint of the certificate (64 hex chars)
  2. Or provide a valid base64-encoded value of the digest
  3. Trim whitespace/quotes from the config values and re-run nats-server -t to validate
  4. Verify the fingerprint with: openssl x509 -in cert.pem -noout -fingerprint -sha256

Example fix

// before
gateway { pinned_certs: ["/etc/certs/server.crt"] }
// after
gateway { pinned_certs: ["AB12CD34...98EF"] }  # 64-char SHA-256 hex fingerprint
Defensive patterns

Strategy: validation

Validate before calling

re := regexp.MustCompile(`^([0-9a-fA-F]{64}|[A-Za-z0-9+/=]+)$`)
for _, c := range opts.Gateway.TLSPinnedCerts {
    if !re.MatchString(c) { return fmt.Errorf("bad pinned cert %q", c) }
}

Try / catch

err := server.ValidateOptions(opts)
if err != nil && strings.Contains(err.Error(), "pinned") {
    // fix the gateway pinned_certs entries, then retry
}

Prevention

When it happens

Trigger: Options.Gateway.TLSPinnedCerts contains an entry that fails validatePinnedCerts (not 64-char hex, not valid base64) during gateway option validation at startup.

Common situations: Copying a certificate file path instead of the fingerprint into pinned_certs, truncated SHA-256 digests, whitespace/quotes around the value, or using SHA-1 fingerprints where SHA-256 is expected.

Related errors


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