OpenNHP/opennhp · error
relay: server # publicKeyBase64 invalid
Error message
relay: server #%d publicKeyBase64 invalid: %w
What it means
normalize decodes each server's publicKeyBase64 via utils.PubKeyFingerprintFromBase64 to compute a fingerprint; this error wraps the decode failure with the server index. The value must be valid base64 encoding of an acceptable public key format (e.g. Curve25519).
Solutions
- Re-copy the server's public key exactly as output by keygen, without quotes, whitespace, or truncation
- Verify the key decodes with `base64 -d` to the expected byte length
- Confirm key algorithm matches the relay's cipher scheme (curve vs sm2) and use the corresponding keygen output
- Ensure you are using the server's public key, not its private key
Example fix
// before pubKeyBase64 = "<server pubkey>" // after pubKeyBase64 = "dGVzdC1wdWJsaWMta2V5LWJhc2U2NC1zdHJpbmc="
Defensive patterns
Strategy: validation
Validate before calling
raw := strings.TrimSpace(cfg.Servers[i].PubKeyBase64)
b, err := base64.StdEncoding.DecodeString(raw)
if err != nil || len(b) != 32 { // curve25519
return fmt.Errorf("server #%d pubkey not valid base64 32-byte key", i)
} Try / catch
if err := cfg.Normalize(); err != nil {
if strings.Contains(err.Error(), "publicKeyBase64 invalid") {
return fmt.Errorf("re-copy the server key from keygen output verbatim: %w", err)
}
return err
} Prevention
- Copy keys with a tool (pbpaste/xclip) rather than retyping
- Verify keys decode with `base64 -d | wc -c` before committing configs
- Use the matching keygen algorithm (curve vs sm2) for your cipher scheme
When it happens
Trigger: PubKeyFingerprintFromBase64 returns an error for server i — the publicKeyBase64 string is not valid base64, has whitespace/quotes/newlines embedded, decodes to the wrong key length, or contains a placeholder like "<server pubkey>".
Common situations: Pasting a key with surrounding quotes or line breaks; truncating the key during copy/paste; putting an SM2 key where Curve is expected (or vice versa); placeholder text left in from a template; using the private key instead of the public key.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- relay: server # missing publicKeyBase64
- relay: server # and # share the same publicKeyBase64…
- private key parse error
- private key parse error
- private key parse error
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/80f73dd3338deb38.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/relay/config.go:233
// change the instance" mistake. The dedupe key is (fingerprint, addr),
// NOT addr alone: resolveTarget routes by PeerPk, so two DISTINCT
// pubkeys legitimately sharing one host:port (a SNI/header-routed
// front-end, or port-multiplexed identities) is a valid topology and
// must not be a hard config-load failure. Only same-pubkey + same-addr
// is the unambiguous copy-paste error.
type addrOrigin struct {
server int
instance int
}
seenAddr := make(map[string]addrOrigin)
for i := range cfg.Servers {
c := &cfg.Servers[i]
if c.PubKeyBase64 == "" {
return fmt.Errorf("relay: server #%d missing publicKeyBase64", i)
}
fp, err := utils.PubKeyFingerprintFromBase64(c.PubKeyBase64)
if err != nil {
return fmt.Errorf("relay: server #%d publicKeyBase64 invalid: %w", i, err)
}
if dup, ok := seenFP[fp]; ok {
return fmt.Errorf("relay: server #%d and #%d share the same publicKeyBase64 (fingerprint %s)", dup, i, fp)
}
seenFP[fp] = i
if len(c.Instances) == 0 {
return fmt.Errorf("relay: server #%d (fingerprint %s) has no [[Servers.Instances]]", i, fp)
}
for j := range c.Instances {
inst := &c.Instances[j]
if inst.Host == "" {
return fmt.Errorf("relay: server #%d instance #%d missing host", i, j)
}
if inst.Port <= 0 {
return fmt.Errorf("relay: server #%d instance #%d missing or invalid port", i, j)
}
addr := fmt.Sprintf("%s:%d", inst.Host, inst.Port)View on GitHub (pinned to 6e04ca5ff0)