{"record":{"id":"b7776c879692c230","repo":"nats-io/nats-server","slug":"gateway-q-v","errorCode":null,"errorMessage":"gateway %q: %v","messagePattern":"gateway %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/gateway.go","lineNumber":328,"sourceCode":"\tif o.Gateway.Name == _EMPTY_ {\n\t\treturn errors.New(\"gateway has no name\")\n\t}\n\tif strings.Contains(o.Gateway.Name, \" \") {\n\t\treturn ErrGatewayNameHasSpaces\n\t}\n\tif o.Gateway.Port == 0 {\n\t\treturn fmt.Errorf(\"gateway %q has no port specified (select -1 for random port)\", o.Gateway.Name)\n\t}\n\tfor i, g := range o.Gateway.Gateways {\n\t\tif g.Name == _EMPTY_ {\n\t\t\treturn fmt.Errorf(\"gateway in the list %d has no name\", i)\n\t\t}\n\t\tif len(g.URLs) == 0 {\n\t\t\treturn fmt.Errorf(\"gateway %q has no URL\", g.Name)\n\t\t}\n\t}\n\tif err := validatePinnedCerts(o.Gateway.TLSPinnedCerts); err != nil {\n\t\treturn fmt.Errorf(\"gateway %q: %v\", o.Gateway.Name, err)\n\t}\n\treturn nil\n}\n\n// Computes a hash of 6 characters for the name.\n// This will be used for routing of replies.\nfunc getGWHash(name string) []byte {\n\treturn []byte(getHashSize(name, gwHashLen))\n}\n\nfunc getOldHash(name string) []byte {\n\tsha := sha256.New()\n\tsha.Write([]byte(name))\n\tfullHash := []byte(fmt.Sprintf(\"%x\", sha.Sum(nil)))\n\treturn fullHash[:4]\n}\n\n// Initialize the s.gateway structure. We do this even if the server","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/gateway.go#L310-L346","documentation":"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.","triggerScenarios":"Options.Gateway.TLSPinnedCerts contains an entry that fails validatePinnedCerts (not 64-char hex, not valid base64) during gateway option validation at startup.","commonSituations":"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.","solutions":["Replace each pinned_certs entry with the full hex-encoded SHA-256 fingerprint of the certificate (64 hex chars)","Or provide a valid base64-encoded value of the digest","Trim whitespace/quotes from the config values and re-run nats-server -t to validate","Verify the fingerprint with: openssl x509 -in cert.pem -noout -fingerprint -sha256"],"exampleFix":"// before\ngateway { pinned_certs: [\"/etc/certs/server.crt\"] }\n// after\ngateway { pinned_certs: [\"AB12CD34...98EF\"] }  # 64-char SHA-256 hex fingerprint","handlingStrategy":"validation","validationCode":"re := regexp.MustCompile(`^([0-9a-fA-F]{64}|[A-Za-z0-9+/=]+)$`)\nfor _, c := range opts.Gateway.TLSPinnedCerts {\n    if !re.MatchString(c) { return fmt.Errorf(\"bad pinned cert %q\", c) }\n}","typeGuard":null,"tryCatchPattern":"err := server.ValidateOptions(opts)\nif err != nil && strings.Contains(err.Error(), \"pinned\") {\n    // fix the gateway pinned_certs entries, then retry\n}","preventionTips":["Store SHA-256 hex fingerprints (64 chars), never file paths","Generate fingerprints via openssl x509 -noout -fingerprint -sha256","Trim whitespace and quotes from values in config tooling","Validate gateway TLS config with nats-server -t before rollout"],"tags":["tls","gateway","validation"],"backgroundTag":"invalid-certificate-fingerprint","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}