{"record":{"id":"823ab693a2c6b90b","repo":"AdguardTeam/AdGuardHome","slug":"reading-cert-file-w","errorCode":null,"errorMessage":"reading cert file: %w","messagePattern":"reading cert file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/aghtls/defaultmanager.go","lineNumber":651,"sourceCode":"\t}\n\n\treturn certErr\n}\n\n// loadCertificateChainData loads PEM-encoded certificates chain data to the\n// TLS configuration. tlsConf must be not nil. tlsConf.CertificateChainData\n// struct field will be modified in case tlsConfig.CertificatePath is not an\n// empty string.  extTLSConf must not be nil.\nfunc loadCertificateChainData(extTLSConf *ExtendedTLSConfig) (err error) {\n\textTLSConf.CertificateChainData = []byte(extTLSConf.CertificateChain)\n\tif extTLSConf.CertificatePath != \"\" {\n\t\tif extTLSConf.CertificateChain != \"\" {\n\t\t\treturn errors.Error(\"certificate data and file can't be set together\")\n\t\t}\n\n\t\textTLSConf.CertificateChainData, err = os.ReadFile(extTLSConf.CertificatePath)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"reading cert file: %w\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// loadPrivateKeyData loads PEM-encoded private key data to the TLS\n// configuration. tlsConf must be not nil. tlsConf.PrivateKeyData struct field\n// will be modified in case tlsConfig.PrivateKeyPath is not an empty string.\n// extTLSConf must not be nil.\nfunc loadPrivateKeyData(extTLSConf *ExtendedTLSConfig) (err error) {\n\textTLSConf.PrivateKeyData = []byte(extTLSConf.PrivateKey)\n\tif extTLSConf.PrivateKeyPath != \"\" {\n\t\tif extTLSConf.PrivateKey != \"\" {\n\t\t\treturn errors.Error(\"private key data and file can't be set together\")\n\t\t}\n\n\t\textTLSConf.PrivateKeyData, err = os.ReadFile(extTLSConf.PrivateKeyPath)","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghtls/defaultmanager.go#L633-L669","documentation":"The manager could not read the TLS certificate file from disk while loading the TLS configuration. It wraps an os.ReadFile failure such as ENOENT or EACCES on the configured CertificatePath.","triggerScenarios":"LoadTLSConfig with a CertificatePath that does not exist, is a directory, or lacks read permission for the process. Also triggered if both CertificateChain data and CertificatePath are set (guarded by a preceding error) or the file disappears between config and read.","commonSituations":"Wrong path in config (missing /etc/adguardhome or volume mount); cert file not yet provisioned by cert-manager/acme at startup; Docker bind-mount with wrong ownership; path with a typo.","solutions":["Verify the file exists and is readable: ls -l /path/to/cert.pem and run as a user with read access","If certs are provisioned asynchronously, delay startup or retry LoadTLSConfig until the file appears","Fix the configured path to point to the actual certificate file (not a directory)","In containers, check the volume mount maps the file correctly"],"exampleFix":"// before\ncertificate_path: /etc/ssl/certs # directory, not the cert\n// after\ncertificate_path: /etc/ssl/certs/example.com.fullchain.pem","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(conf.CertificatePath); err != nil || info.IsDir() {\n    return fmt.Errorf(\"certificate path invalid: %s\", conf.CertificatePath)\n}","typeGuard":null,"tryCatchPattern":"if err := mgr.LoadTLSConfig(ctx, conf); err != nil {\n    if errors.Is(err, fs.ErrNotExist) { /* provision cert, retry */ }\n}","preventionTips":["Do not set both CertificateChain and CertificatePath","Gate startup on cert file existence when using async provisioners","Use absolute paths in configuration"],"tags":["tls","filesystem","configuration","startup"],"backgroundTag":"certificate-file-not-found","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}