{"record":{"id":"87ef9edbed6425a6","repo":"OpenNHP/opennhp","slug":"load-db-peer-config-err-optional-v","errorCode":null,"errorMessage":"load db peer config err (optional): %v","messagePattern":"load db peer config err \\(optional\\): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"endpoints/server/config.go","lineNumber":323,"sourceCode":"\tif updateErr := s.updateAgentPeers(agentPeers.Agents); updateErr != nil {\n\t\t// ignore error\n\t\t_ = updateErr\n\t}\n\n\tagentConfigWatch = utils.WatchFile(fileNameAgent, func() {\n\t\tlog.Info(\"agent peer config: %s has been updated\", fileNameAgent)\n\t\tif contentAgent, err = s.loadConfigFile(fileNameAgent); err == nil {\n\t\t\tif err = toml.Unmarshal(contentAgent, &agentPeers); err == nil {\n\t\t\t\t_ = s.updateAgentPeers(agentPeers.Agents)\n\t\t\t}\n\t\t}\n\t})\n\n\t//db.toml (optional)\n\tfileNameDE := filepath.Join(ExeDirPath, \"etc\", \"db.toml\")\n\tcontentDE, err := s.loadConfigFile(fileNameDE)\n\tif err != nil {\n\t\tlog.Warning(\"load db peer config err (optional): %v\", err)\n\t} else {\n\t\tvar dePeers Peers\n\t\tif unmarshalErr := toml.Unmarshal(contentDE, &dePeers); unmarshalErr != nil {\n\t\t\tlog.Error(\"failed to unmarshal db peers config: %v\", unmarshalErr)\n\t\t}\n\t\tif updateErr := s.updateDePeers(dePeers.DBs); updateErr != nil {\n\t\t\t// ignore error\n\t\t\t_ = updateErr\n\t\t}\n\t\tdbConfigWatch = utils.WatchFile(fileNameDE, func() {\n\t\t\tlog.Info(\"device peer config: %s has been updated\", fileNameDE)\n\t\t\tif contentDE, err = s.loadConfigFile(fileNameDE); err == nil {\n\t\t\t\tif err = toml.Unmarshal(contentDE, &dePeers); err == nil {\n\t\t\t\t\t_ = s.updateDePeers(dePeers.DBs)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/config.go#L305-L341","documentation":"During NHP-Server startup, loadPeers reads optional peer config files from <ExeDirPath>/etc/. For db.toml (NHP-DB Data Broker peers), a load failure is intentionally non-fatal: the server logs 'load db peer config err (optional): %v' at Warning level and continues running without DB peer entries. It exists so deployments that do not use DHP/database brokering do not need the file.","triggerScenarios":"s.loadConfigFile on <ExeDirPath>/etc/db.toml fails during Start -> loadPeers: (1) the file simply does not exist, (2) wrong executable directory so ExeDirPath/etc does not contain db.toml, (3) file permission error preventing read.","commonSituations":"Fresh deployment where only config.toml/agent.toml were provisioned because DHP is not used; running the daemon from a different working directory than expected so ExeDirPath/etc resolves elsewhere; packaging/deploy scripts that skip db.toml; restrictive file permissions after a container/image change.","solutions":["If DB peers are needed, create <ExeDirPath>/etc/db.toml with a valid [[DBs]] table and restart the server.","If DB brokering is not used, safely ignore this warning — it is explicitly optional.","Verify the daemon is launched from the directory containing etc/db.toml (ExeDirPath resolution) or place the file at the expected absolute path.","Check file permissions so the daemon user can read db.toml.","Ensure the TOML parses (toml.Unmarshal) and [[DBs]] entries pass updateDePeers, otherwise a separate error is logged."],"exampleFix":"# before: missing optional file triggers warning\n$ ls etc/\nconfig.toml  agent.toml\n\n# after: provision db.toml\n# etc/db.toml\n[[DBs]]\nId = \"db-1\"\nAddr = \"10.0.0.5:6100\"\nPublicKey = \"...\"","handlingStrategy":"validation","validationCode":"# check the optional config exists and parses before starting the server\nf=\"$EXE_DIR/etc/db.toml\"\nif [ -f \"$f\" ]; then\n    python3 -c \"import tomllib;tomllib.load(open('$f','rb'))\" || echo \"db.toml invalid TOML\"\nelse\n    echo \"db.toml absent — DB brokering disabled (warning expected)\"\nfi","typeGuard":"// Go: probe the optional file exactly as loadPeers does\nfunc dbPeerConfigAvailable() bool {\n    _, err := os.Stat(filepath.Join(utils.ExeDirPath, \"etc\", \"db.toml\"))\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["Provision etc/db.toml whenever DHP/database brokering is part of the deployment","Run the daemon from the directory that contains its etc/ tree so ExeDirPath resolves correctly","Keep config files readable by the daemon's runtime user in containers/images","Treat this warning as expected in DB-less deployments — document it in the deployment runbook","Validate TOML syntax in CI before shipping config bundles"],"tags":["config","toml","optional","startup"],"backgroundTag":"config-file-not-found","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}