{"record":{"id":"4f6eb717dccfdcfd","repo":"hashicorp/nomad","slug":"unauthorized-raft-connection-from-s-v","errorCode":null,"errorMessage":"unauthorized raft connection from %s: %v","messagePattern":"unauthorized raft connection from (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/rpc.go","lineNumber":925,"sourceCode":"}\n\nfunc (r *rpcHandler) validateRaftTLS(rpcCtx *RPCContext) error {\n\t// TLS is not configured or not to be enforced\n\ttlsConf := r.srv.config.TLSConfig\n\tif !tlsConf.EnableRPC || !tlsConf.VerifyServerHostname || tlsConf.RPCUpgradeMode {\n\t\treturn nil\n\t}\n\n\t// check that `server.<region>.nomad` is present in cert\n\texpected := \"server.\" + r.srv.Region() + \".nomad\"\n\terr := rpcCtx.ValidateCertificateForName(expected)\n\tif err != nil {\n\t\tcert := rpcCtx.Certificate()\n\t\tif cert != nil {\n\t\t\terr = fmt.Errorf(\"request certificate is only valid for %s: %v\", cert.DNSNames, err)\n\t\t}\n\n\t\treturn fmt.Errorf(\"unauthorized raft connection from %s: %v\", rpcCtx.Conn.RemoteAddr(), err)\n\t}\n\n\t// Certificate is valid for the expected name\n\treturn nil\n}\n","sourceCodeStart":907,"sourceCodeEnd":931,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/rpc.go#L907-L931","documentation":"validateRaftTLS rejects incoming raft connections whose certificate is not valid for the expected server.<region>.nomad name, wrapping any prior error (including the name-mismatch detail) into this unauthorized-connection error. It is a security gate: the server refuses raft RPCs from peers it cannot cryptographically verify as servers for this region.","triggerScenarios":"Any raft/TLS connection to a Nomad server where the presented certificate fails ValidateCertificateForName for server.<region>.nomad — wrong-region cert, expired or untrusted cert chain, or non-server certificate.","commonSituations":"Cert rotation mistakes (new certs missing region SANs); mixing clusters with different CAs; clients accidentally connecting to server RPC ports; region config typos making expected name differ from cert names.","solutions":["Re-issue server certificates with server.<region>.nomad in CN or DNS SANs and a chain trusted by both peers","Confirm both servers share the same CA and region configuration","Check server logs for the wrapped 'request certificate is only valid for' detail to see the cert's actual names","Fix region name mismatches between nomad config and certificate names"],"exampleFix":"// before\nregion = \"us-east-2\"  # cert is for server.us-east-1.nomad\n// after\nregion = \"us-east-1\"  # matches certificate, or re-issue cert for us-east-2","handlingStrategy":"validation","validationCode":"cert, _ := tls.LoadX509Certificate(\"server.pem\")\nif cert == nil || !slices.Contains(cert.DNSNames, \"server.\"+region+\".nomad\") {\n    return fmt.Errorf(\"server cert not authorized for region %s\", region)\n}","typeGuard":"func isRaftAuthzError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"unauthorized raft connection\")\n}","tryCatchPattern":"if err := connectRaft(peer); err != nil && isRaftAuthzError(err) {\n    return fmt.Errorf(\"peer cert rejected; verify CA trust and server.<region>.nomad SAN: %w\", err)\n}","preventionTips":["Share one trusted CA across all servers in the cluster","Keep region config consistent with certificate names","Rotate certificates with automation that always emits region-scoped SANs"],"tags":["nomad","tls","raft","unauthorized","security"],"backgroundTag":"unauthorized-raft-connection","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}