{"record":{"id":"ff979637ade19303","repo":"OpenNHP/opennhp","slug":"failed-to-create-device-v-ff9796","errorCode":null,"errorMessage":"failed to create device %v","messagePattern":"failed to create device (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"endpoints/db/udpdevice.go","lineNumber":145,"sourceCode":"\tlog.Info(\"=== REVISION %s ===\", version.CommitId)\n\tlog.Info(\"=== RELEASE %s                       ===\", version.BuildTime)\n\tlog.Info(\"=========================================================\")\n\n\terr = a.loadBaseConfig()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tprk, err := base64.StdEncoding.DecodeString(a.config.PrivateKeyBase64)\n\tif err != nil {\n\t\tlog.Error(\"private key parse error %v\\n\", err)\n\t\treturn fmt.Errorf(\"private key parse error %v\", err)\n\t}\n\n\ta.device = core.NewDevice(core.NHP_DB, prk, nil)\n\tif a.device == nil {\n\t\tlog.Critical(\"failed to create device %v\\n\", err)\n\t\treturn fmt.Errorf(\"failed to create device %v\", err)\n\t}\n\n\ta.remoteConnectionMap = make(map[string]*UdpConn)\n\ta.serverPeerMap = make(map[string]*core.UdpPeer)\n\n\t// load peers\n\t_ = a.loadPeers()\n\n\t// load TEEs\n\t_ = a.loadTEEs()\n\n\ta.signals.stop = make(chan struct{})\n\ta.signals.serverMapUpdated = make(chan struct{}, 1)\n\ta.recvMsgCh = a.device.DecryptedMsgQueue\n\ta.sendMsgCh = make(chan *core.MsgData, core.SendQueueSize)\n\n\t// start device routines\n\ta.device.Start()","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/db/udpdevice.go#L127-L163","documentation":"After the private key decodes, Start calls core.NewDevice(core.NHP_DB, prk, nil). NewDevice returns nil when it cannot construct the protocol device (e.g. the decoded key material is rejected at the crypto layer or an internal invariant fails). Start logs a critical message and returns 'failed to create device <err>' so the daemon exits instead of running half-initialized.","triggerScenarios":"Calling Start (via `nhp-device run`) where core.NewDevice returns nil — typically because the decoded private key bytes are structurally invalid for the device's cipher scheme even though base64 decoding succeeded.","commonSituations":"A base64 string that decodes but is not a valid SM2/Curve25519 private key (wrong byte length, all zeros, a public key mistakenly configured); keys migrated between cipher schemes; corrupted key files restored from backups.","solutions":["Regenerate the identity key with `nhp-device keygen` and replace privateKeyBase64 in config.toml","Verify the key length/type matches the device's cipher scheme (SM2 vs Curve25519)","Diff the configured key against the last known-good value in your secret store","Check the accompanying log.Critical output for the underlying device-construction cause"],"exampleFix":"// before (config.toml, decodes but invalid key bytes)\nprivateKeyBase64 = \"AAAA\"\n// after\nprivateKeyBase64 = \"<valid key from `nhp-device keygen --json`>\"","handlingStrategy":"try-catch","validationCode":"const key = Buffer.from(config.privateKeyBase64, 'base64');\n// reject obviously invalid key material before startup\nif (key.length === 0 || key.every(b => b === 0)) {\n  throw new Error('decoded private key is empty or all zeros; regenerate with nhp-device keygen');\n}","typeGuard":"const isPlausibleKeyMaterial = (b64) => { const b = Buffer.from(b64 ?? '', 'base64'); return b.length >= 32 && !b.every(x => x === 0); };","tryCatchPattern":"if err := device.Start(); err != nil {\n  if strings.HasPrefix(err.Error(), \"failed to create device\") {\n    log.Fatalf(\"device init failed (%v): regenerate keys with `nhp-device keygen` and update config\", err)\n  }\n  return err\n}","preventionTips":["Regenerate keys with `nhp-device keygen` whenever device init fails","Keep cipher scheme consistent between key generation and device config","Restore keys only from verified secret-store backups","Fail fast in deployment scripts by starting the device and checking for immediate exit"],"tags":["startup","cryptography","keys","device"],"backgroundTag":"module-init-failed","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}