OpenNHP/opennhp · error
relay: server invalid publicKeyBase64
Error message
relay: server %q invalid publicKeyBase64: %w
What it means
Raised in RelayServer.buildServer while converting a configured [[Servers]] entry into runtime state: decoding that server's PubKeyBase64 with standard base64 failed. The peer public key copied into the relay config for this upstream NHP server is malformed or was pasted in the wrong encoding.
Solutions
- Re-copy the server's public key from its config or keygen output into the relay config
- Remove surrounding whitespace/newlines introduced during copy-paste
- Confirm standard (not URL-safe) base64 is used
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at endpoints/relay/relay.go:257 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/b8e8f06354d80abf.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/relay/relay.go:257
log.Info("[Relay] initialized, relay pubkey=%s, %d server(s)",
device.PublicKeyBase64(), len(rs.servers))
for _, cr := range rs.servers {
log.Info("[Relay] server id=%s name=%q lb=%s instances=%d",
cr.id, cr.name, cr.scheme, len(cr.instances))
for _, inst := range cr.instances {
log.Info("[Relay] upstream %s:%d (weight=%d)",
inst.host, inst.port, inst.weight)
}
}
return rs, nil
}
// buildServer turns a config Server into runtime state, registering each
// instance as a peer on the NHP device.
func (rs *RelayServer) buildServer(c *Server) (*serverRuntime, error) {
pubKey, err := base64.StdEncoding.DecodeString(c.PubKeyBase64)
if err != nil {
return nil, fmt.Errorf("relay: server %q invalid publicKeyBase64: %w", c.Name, err)
}
id := utils.PubKeyFingerprint(pubKey)
sticky := false // default: per-request load balancing
if c.StickyInstance != nil {
sticky = *c.StickyInstance
}
cr := &serverRuntime{
id: id,
name: c.Name,
pubKey: pubKey,
pubKeyBase64: c.PubKeyBase64,
scheme: c.LoadBalance,
sticky: sticky,
instances: make([]*serverInstance, 0, len(c.Instances)),
}
for j := range c.Instances {View on GitHub (pinned to 6e04ca5ff0)