OpenNHP/opennhp · warning
load db peer config err (optional)
Error message
load db peer config err (optional): %v
What it means
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.
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.
Example fix
# before: missing optional file triggers warning $ ls etc/ config.toml agent.toml # after: provision db.toml # etc/db.toml [[DBs]] Id = "db-1" Addr = "10.0.0.5:6100" PublicKey = "..."
Defensive patterns
Strategy: validation
Validate before calling
# check the optional config exists and parses before starting the server
f="$EXE_DIR/etc/db.toml"
if [ -f "$f" ]; then
python3 -c "import tomllib;tomllib.load(open('$f','rb'))" || echo "db.toml invalid TOML"
else
echo "db.toml absent — DB brokering disabled (warning expected)"
fi Type guard
// Go: probe the optional file exactly as loadPeers does
func dbPeerConfigAvailable() bool {
_, err := os.Stat(filepath.Join(utils.ExeDirPath, "etc", "db.toml"))
return err == nil
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.
Related errors
- load relay peer config err (optional)
- server peer config invalid on initial load
- config load error
- relay: failed to parse config
- private key parse error
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/87ef9edbed6425a6.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/server/config.go:323
if updateErr := s.updateAgentPeers(agentPeers.Agents); updateErr != nil {
// ignore error
_ = updateErr
}
agentConfigWatch = utils.WatchFile(fileNameAgent, func() {
log.Info("agent peer config: %s has been updated", fileNameAgent)
if contentAgent, err = s.loadConfigFile(fileNameAgent); err == nil {
if err = toml.Unmarshal(contentAgent, &agentPeers); err == nil {
_ = s.updateAgentPeers(agentPeers.Agents)
}
}
})
//db.toml (optional)
fileNameDE := filepath.Join(ExeDirPath, "etc", "db.toml")
contentDE, err := s.loadConfigFile(fileNameDE)
if err != nil {
log.Warning("load db peer config err (optional): %v", err)
} else {
var dePeers Peers
if unmarshalErr := toml.Unmarshal(contentDE, &dePeers); unmarshalErr != nil {
log.Error("failed to unmarshal db peers config: %v", unmarshalErr)
}
if updateErr := s.updateDePeers(dePeers.DBs); updateErr != nil {
// ignore error
_ = updateErr
}
dbConfigWatch = utils.WatchFile(fileNameDE, func() {
log.Info("device peer config: %s has been updated", fileNameDE)
if contentDE, err = s.loadConfigFile(fileNameDE); err == nil {
if err = toml.Unmarshal(contentDE, &dePeers); err == nil {
_ = s.updateDePeers(dePeers.DBs)
}
}
})
}View on GitHub (pinned to 6e04ca5ff0)