{"record":{"id":"4e9e4631584c8dd3","repo":"hashicorp/nomad","slug":"error-validating-s-w","errorCode":null,"errorMessage":"error validating %s: %w","messagePattern":"error validating (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/auth/oidc/client_assertion.go","lineNumber":145,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error reading %s: %w\", source, err)\n\t\t}\n\t}\n\t// or pem string\n\tif k.PemKey != \"\" {\n\t\tsource = \"PemKey\"\n\t\tbts = []byte(k.PemKey)\n\t}\n\n\t// ensure newlines around pem header/footer\n\tbts = newlineHeaders(bts)\n\n\tkey, err = gojwt.ParseRSAPrivateKeyFromPEM(bts)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing %s: %w\", source, err)\n\t}\n\tif err := key.Validate(); err != nil {\n\t\treturn nil, fmt.Errorf(\"error validating %s: %w\", source, err)\n\t}\n\treturn key, nil\n}\n\n// getCassCert parses the structs.OIDCClientAssertionKey PemCertFile\n// or PemCert, depending on which is set.\nfunc getCassCert(k *structs.OIDCClientAssertionKey) (*x509.Certificate, error) {\n\tvar bts []byte\n\tvar err error\n\tvar source string // for informative error messages\n\n\t// pem file on disk\n\tif k.PemCertFile != \"\" {\n\t\tsource = \"PemCertFile\"\n\t\tbts, err = os.ReadFile(k.PemCertFile)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error reading %s: %w\", source, err)\n\t\t}","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/lib/auth/oidc/client_assertion.go#L127-L163","documentation":"The PEM parsed successfully into an RSA private key, but key.Validate() rejected it — the key's internal parameters are inconsistent (e.g. primes/exponent don't match, precomputation invalid). This indicates a corrupted or malformed key rather than a formatting problem.","triggerScenarios":"BuildClientAssertionJWT → getCassPrivateKey after successful parse, when rsa.PrivateKey.Validate() fails due to mathematically inconsistent key material (usually corruption or tampering).","commonSituations":"Key file damaged in transit or by a templating tool; hand-edited PEM; key generated by a broken tooling; truncated/partial paste that still parses in degraded form.","solutions":["Re-generate a fresh RSA key pair: `openssl genrsa -out client.key 2048 && openssl rsa -in client.key -pubout -out client.pub`.","Verify the existing key with `openssl rsa -in key.pem -check -noout` and replace it if invalid.","Re-provision the key from the secret store rather than re-using the corrupted copy."],"exampleFix":"// before: corrupted key reused\nPemKeyFile: \"/secrets/damaged-client.key\"\n// after: freshly generated and validated key\nPemKeyFile: \"/secrets/client.key\" // openssl rsa -check passed","handlingStrategy":"validation","validationCode":"func precheckKeyMaterial(bts []byte) error {\n  key, err := gojwt.ParseRSAPrivateKeyFromPEM(bts)\n  if err != nil { return err }\n  if err := key.Validate(); err != nil {\n    return fmt.Errorf(\"key math invalid, regenerate: %w\", err)\n  }\n  return nil\n}","typeGuard":null,"tryCatchPattern":"key, err := getCassPrivateKey(k)\nif err != nil && strings.Contains(err.Error(), \"error validating\") {\n  return fmt.Errorf(\"key corrupted; regenerate and re-provision: %w\", err)\n}","preventionTips":["Regenerate any key that fails `openssl rsa -check`.","Provision keys from a secret store rather than copying between environments.","Avoid hand-editing PEM files; re-export with openssl instead."],"tags":["oidc","client-assertion","rsa","key-validation","corruption"],"backgroundTag":"invalid-private-key","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"}