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

  1. Regenerate the relay key pair and update PrivateKeyBase64 in config.toml
  2. Verify the key length matches what core.NewDevice expects for the configured cipher scheme
  3. 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] = cr

View on GitHub (pinned to 6e04ca5ff0)