{"record":{"id":"0bdb2c9e55639d94","repo":"nats-io/nats-server","slug":"mqtt-v","errorCode":null,"errorMessage":"mqtt: %v","messagePattern":"mqtt: %v","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":739,"sourceCode":"\t\t\treturn errMQTTTokenMixWIthUsersNKeys\n\t\t}\n\t}\n\tif mo.AckWait < 0 {\n\t\treturn errMQTTAckWaitMustBePositive\n\t}\n\tif mo.JSAPITimeout < 0 {\n\t\treturn errMQTTJSAPITimeoutMustBePositive\n\t}\n\t// If strictly standalone and there is no JS enabled, then it won't work...\n\t// For leafnodes, we could either have remote(s) and it would be ok, or no\n\t// remote but accept from a remote side that has \"hub\" property set, which\n\t// then would ok too. So we fail only if we have no leafnode config at all.\n\tif !o.JetStream && o.Cluster.Port == 0 && o.Gateway.Port == 0 &&\n\t\to.LeafNode.Port == 0 && len(o.LeafNode.Remotes) == 0 {\n\t\treturn errMQTTStandaloneNeedsJetStream\n\t}\n\tif err := validatePinnedCerts(mo.TLSPinnedCerts); err != nil {\n\t\treturn fmt.Errorf(\"mqtt: %v\", err)\n\t}\n\tif mo.ConsumerReplicas > 0 && mo.StreamReplicas > 0 && mo.ConsumerReplicas > mo.StreamReplicas {\n\t\treturn fmt.Errorf(\"mqtt: consumer_replicas (%v) cannot be higher than stream_replicas (%v)\",\n\t\t\tmo.ConsumerReplicas, mo.StreamReplicas)\n\t}\n\treturn nil\n}\n\n// Returns true if this connection is from a MQTT client.\n// Lock held on entry.\nfunc (c *client) isMqtt() bool {\n\treturn c.mqtt != nil\n}\n\n// If this is an MQTT client, returns the session client ID,\n// otherwise returns the empty string.\n// Lock held on entry\nfunc (c *client) getMQTTClientID() string {","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L721-L757","documentation":"MQTT config validation wraps the failure of validatePinnedCerts (which checks the format of tls_pinned_certs entries) with the 'mqtt: ' prefix. The MQTT option block references TLS pinned certs that fail validation, so the server refuses to start.","triggerScenarios":"Setting mqtt.tls_pinned_certs with an entry not matching the accepted cert-pin formats (e.g. missing curve/type prefix); calling ValidateMqttOpts on an Options struct with malformed TLSPinnedCerts.","commonSituations":"Copying a pinned-cert entry from documentation for a different scheme; hand-editing the mqtt config block; typos in the base64 or SHA fingerprint of the pinned certificate.","solutions":["Read the wrapped %v inner error to identify which cert entry is malformed","Fix each pinned cert entry to the accepted format (e.g. 'rsa:HEX' / 'ecdsa:HEX' / 'x509:base64' style used by validatePinnedCerts)","Regenerate the fingerprint from the actual client certificate if the value was copied from elsewhere"],"exampleFix":"// before (nats-server.conf)\nmqtt {\n  tls_pinned_certs: [\"abcdef1234\"]\n}\n// after\nmqtt {\n  tls_pinned_certs: [\"sha256:abcdef1234\"]\n}","handlingStrategy":"validation","validationCode":"// before starting the server, validate options\nif len(o.Mqtt.TLSPinnedCerts) > 0 {\n\tfor _, c := range o.Mqtt.TLSPinnedCerts {\n\t\t// entries must use the accepted pin scheme, e.g. \"sha256:<hex>\"\n\t\tif !strings.Contains(c, \":\") {\n\t\t\treturn fmt.Errorf(\"mqtt pinned cert %q lacks scheme prefix\", c)\n\t\t}\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := srv.ValidateMqttOpts(); err != nil {\n\tvar inner error\n\tif strings.HasPrefix(err.Error(), \"mqtt: \") {\n\t\tinner = errors.Unwrap(err) // inspect wrapped cert error\n\t}\n\treturn fmt.Errorf(\"mqtt config invalid: %v\", inner)\n}","preventionTips":["Copy pinned-cert formats exactly from the validated examples (scheme-prefixed fingerprints)","Run nats-server with --signal reload or a config lint step before production deploys","Keep TLS pin entries generated by a script, not hand-typed"],"tags":["mqtt","tls","configuration"],"backgroundTag":"invalid-tls-pinned-certs","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}