{"record":{"id":"95a832b3b6c00d87","repo":"hashicorp/nomad","slug":"invalid-certificate-s-not-in-s","errorCode":null,"errorMessage":"invalid certificate, %s not in %s","messagePattern":"invalid certificate, (.+?) not in (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/rpc.go","lineNumber":163,"sourceCode":"// ValidateCertificateForName returns true if the RPC context certificate is valid\n// for the given domain name.\nfunc (ctx *RPCContext) ValidateCertificateForName(name string) error {\n\tif ctx == nil || !ctx.TLS {\n\t\treturn nil\n\t}\n\n\tcert := ctx.Certificate()\n\tif cert == nil {\n\t\treturn errors.New(\"missing certificate information\")\n\t}\n\n\tvalidNames := []string{cert.Subject.CommonName}\n\tvalidNames = append(validNames, cert.DNSNames...)\n\tif slices.Contains(validNames, name) {\n\t\treturn nil\n\t}\n\n\treturn fmt.Errorf(\"invalid certificate, %s not in %s\", name, strings.Join(validNames, \",\"))\n}\n\nfunc (ctx *RPCContext) IsStatic() bool {\n\treturn ctx == nil\n}\n\nfunc (ctx *RPCContext) GetRemoteIP() (net.IP, error) {\n\tif ctx == nil {\n\t\treturn nil, nil\n\t}\n\tvar remoteAddr *net.TCPAddr\n\tvar ok bool\n\tif ctx.Session != nil {\n\t\tremoteAddr, ok = ctx.Session.RemoteAddr().(*net.TCPAddr)\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"session address was not a TCP address\")\n\t\t}\n\t}","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/rpc.go#L145-L181","documentation":"validateRaftTLS checks that the certificate presented on a raft-related RPC connection contains the expected name (e.g. server.<region>.nomad) in its CommonName or SAN DNS names. This error means the certificate is technically valid but does not cover the requested name, so the identity check fails.","triggerScenarios":"A server presents a TLS certificate whose CN/DNS SANs do not include the name being validated (e.g. cert issued for server.region1.nomad used in region2), during validateRaftTLS-driven connection handling.","commonSituations":"Certificates issued without proper SAN entries for all regions; reusing one cert across regions; CA templates missing the server.<region>.nomad pattern after adding a new region.","solutions":["Re-issue the certificate including server.<region>.nomad in CN or DNS SANs for every region","Regenerate certificates with the correct region name after adding/renaming a region","Verify with `openssl x509 -text` that DNS names include the expected entry","Update CA/certificate templates to include the region-scoped name pattern"],"exampleFix":"// before\nopenssl req -new -subj '/CN/client.nomad' ...\n// after\nopenssl req -new -subj '/CN/server.us-east-1.nomad' -addext 'subjectAltName=DNS:server.us-east-1.nomad' ...","handlingStrategy":"validation","validationCode":"out, _ := exec.Command(\"openssl\", \"x509\", \"-in\", \"server.pem\", \"-noout\", \"-text\").Output()\nexpected := \"server.\" + region + \".nomad\"\nif !strings.Contains(string(out), expected) {\n    return fmt.Errorf(\"cert missing required SAN %s\", expected)\n}","typeGuard":"func certCoversName(cert *x509.Certificate, name string) bool {\n    names := append([]string{cert.Subject.CommonName}, cert.DNSNames...)\n    return slices.Contains(names, name)\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"invalid certificate\") {\n    return fmt.Errorf(\"re-issue certificate with SAN %s: %w\", expectedName, err)\n}","preventionTips":["Template CAs to always include server.<region>.nomad SANs","Re-verify cert SANs whenever adding or renaming a region","Validate certs with openssl before deploying"],"tags":["nomad","tls","certificate","raft","security"],"backgroundTag":"certificate-name-mismatch","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"}