OpenNHP/opennhp · error
relay: failed to create NHP device
Error message
relay: failed to create NHP device
What it means
Raised in relay New right after core.NewDevice(core.NHP_RELAY, prk, nil) returned nil: the NHP device factory refused the freshly decoded private key, so the relay cannot build its Noise-protocol identity. In practice this means the decoded key bytes are not a valid scalar/key for the configured cipher scheme even though the base64 itself decoded.
Solutions
- Regenerate the relay key pair and update PrivateKeyBase64 in config.toml
- Verify the key length matches what core.NewDevice expects for the configured cipher scheme
- Ensure the key was generated by the matching keygen mode (curve vs sm2)
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at endpoints/relay/relay.go:202 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/5685e2cff98559d3.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/relay/relay.go:202
stats struct {
totalRecvBytes uint64
totalSendBytes uint64
}
}
// New creates a RelayServer from the given configuration.
func New(cfg *Config) (*RelayServer, error) {
// Decode relay private key.
prk, err := base64.StdEncoding.DecodeString(cfg.PrivateKeyBase64)
if err != nil {
return nil, fmt.Errorf("relay: invalid privateKeyBase64: %w", err)
}
// Create NHP device with relay identity.
device := core.NewDevice(core.NHP_RELAY, prk, nil)
if device == nil {
return nil, fmt.Errorf("relay: failed to create NHP device")
}
rs := &RelayServer{
config: cfg,
device: device,
servers: make(map[string]*serverRuntime, len(cfg.Servers)),
sendMsgCh: make(chan *core.MsgData, PacketQueueSizePerConnection),
stopCh: make(chan struct{}),
}
rs.recvMsgCh = device.DecryptedMsgQueue
for i := range cfg.Servers {
c := &cfg.Servers[i]
cr, err := rs.buildServer(c)
if err != nil {
return nil, err
}
rs.servers[cr.id] = crView on GitHub (pinned to 6e04ca5ff0)