{"record":{"id":"8b9e16188c3a0279","repo":"slackhq/nebula","slug":"unable-to-read-pki-cert-file-s-s","errorCode":null,"errorMessage":"unable to read pki.cert file %s: %s","messagePattern":"unable to read pki\\.cert file (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pki.go","lineNumber":328,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar rawCert []byte\n\n\tpubPathOrPEM := c.GetString(\"pki.cert\", \"\")\n\tif pubPathOrPEM == \"\" {\n\t\treturn nil, errors.New(\"no pki.cert path or PEM data provided\")\n\t}\n\n\tif strings.Contains(pubPathOrPEM, \"-----BEGIN\") {\n\t\trawCert = []byte(pubPathOrPEM)\n\t\tpubPathOrPEM = \"<inline>\"\n\n\t} else {\n\t\trawCert, err = os.ReadFile(pubPathOrPEM)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to read pki.cert file %s: %s\", pubPathOrPEM, err)\n\t\t}\n\t}\n\n\tvar crt, v1, v2 cert.Certificate\n\tfor {\n\t\t// Load the certificate\n\t\tcrt, rawCert, err = loadCertificate(rawCert)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif fips140.Enforced() && crt.Curve() != cert.Curve_P256 {\n\t\t\treturn nil, fmt.Errorf(\"pki: use of %s is not allowed in FIPS 140-only mode\", crt.Curve())\n\t\t}\n\n\t\tswitch crt.Version() {\n\t\tcase cert.Version1:\n\t\t\tif v1 != nil {","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/pki.go#L310-L346","documentation":"newCertStateFromConfig loads the certificate chain either from an inline PEM string or by reading the pki.cert file from disk. When the path is a file (not inline PEM) and os.ReadFile fails, this error reports the path and the OS error.","triggerScenarios":"reloadCerts -> newCertStateFromConfig with a pki.cert path that doesn't exist, lacks read permission, is a directory, or otherwise fails os.ReadFile.","commonSituations":"Nebula started from a different working directory with a relative path; cert file deleted or renamed; wrong user/permissions (e.g. running as non-root without access to /etc/nebula); typo in the `cert:` path in config; systemd unit with a different WorkingDirectory.","solutions":["Fix the pki.cert path in config (use an absolute path) and confirm the file exists.","Check file permissions so the nebula process user can read it.","Verify the inline-PEM vs path distinction: an inline PEM string bypasses the file read entirely.","If path is relative, either make it absolute or start nebula from the intended working directory."],"exampleFix":"# before\npki:\n  cert: ./pki.cert\n# after\npki:\n  cert: /etc/nebula/pki.cert","handlingStrategy":"validation","validationCode":"func checkCertReadable(path string) error {\n  if path == \"\" { return errors.New(\"pki.cert path empty\") }\n  fi, err := os.Stat(path)\n  if err != nil { return fmt.Errorf(\"pki.cert %s: %w\", path, err) }\n  if fi.IsDir() { return fmt.Errorf(\"pki.cert %s is a directory\", path) }\n  f, err := os.Open(path); if err != nil { return fmt.Errorf(\"pki.cert %s unreadable: %w\", path, err) }\n  f.Close(); return nil\n}\n// run before starting nebula","typeGuard":null,"tryCatchPattern":"cs, err := newCertStateFromConfig(...)\nif err != nil {\n  var pathErr *os.PathError\n  if strings.Contains(err.Error(), \"unable to read pki.cert file\") && errors.As(err, &pathErr) {\n    return fmt.Errorf(\"fix pki.cert path/permissions: %w\", err)\n  }\n  return err\n}","preventionTips":["Always use absolute paths for pki.cert and ca.crt in the config.","Pre-verify file existence and readability as the exact user nebula runs as (systemd User=).","Add a startup preflight that stats cert paths before launching the service.","Avoid inline-PEM/path ambiguity: inline PEM is detected by content, otherwise treat the value strictly as a path."],"tags":["filesystem","certificate","config","file-not-found"],"backgroundTag":"certificate-file-not-found","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}