{"record":{"id":"bc45a60171190715","repo":"slackhq/nebula","slug":"error-marshalling-v1-certificate-for-handshake-w","errorCode":null,"errorMessage":"error marshalling v1 certificate for handshake: %w","messagePattern":"error marshalling v1 certificate for handshake: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pki.go","lineNumber":429,"sourceCode":"\t\tif v1.Networks()[0] != v2.Networks()[0] {\n\t\t\treturn nil, util.NewContextualError(\"v1 and v2 networks are not the same\", nil, nil)\n\t\t}\n\n\t\tcs.initiatingVersion = dv\n\t}\n\n\tif v1 != nil {\n\t\tif pkcs11backed {\n\t\t\t//NOTE: We do not currently have a method to verify a public private key pair when the private key is in an hsm\n\t\t} else {\n\t\t\tif err := v1.VerifyPrivateKey(privateKeyCurve, privateKey); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"private key is not a pair with public key in nebula cert: %w\", err)\n\t\t\t}\n\t\t}\n\n\t\tv1hs, err := v1.MarshalForHandshakes()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error marshalling v1 certificate for handshake: %w\", err)\n\t\t}\n\t\tncs, err := newCipherSuite(v1.Curve(), pkcs11backed, cipher, fips140.Enforced())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcs.v1Cert = v1\n\t\tcs.v1Credential = handshake.NewCredential(v1, v1hs, privateKey, ncs)\n\n\t\tif cs.initiatingVersion == 0 {\n\t\t\tcs.initiatingVersion = cert.Version1\n\t\t}\n\t}\n\n\tif v2 != nil {\n\t\tif pkcs11backed {\n\t\t\t//NOTE: We do not currently have a method to verify a public private key pair when the private key is in an hsm\n\t\t} else {\n\t\t\tif err := v2.VerifyPrivateKey(privateKeyCurve, privateKey); err != nil {","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/pki.go#L411-L447","documentation":"Wrapping error in newCertState: v1.MarshalForHandshakes failed while preparing the cached wire form of the v1 certificate used during handshakes. The certificate parsed and its key pair verified, but marshalling to the handshake representation errored; the cause is preserved with %w for errors.Is.","triggerScenarios":"newCertState: a v1 certificate passed private-key verification but v1.MarshalForHandshakes() returned an error — malformed/incomplete certificate structure in pki.cert.","commonSituations":"Truncated or hand-edited pki.cert; certificate built by incompatible tooling; bit rot or partial file write.","solutions":["Re-generate the certificate with nebula-cert sign and replace pki.cert","Validate the certificate with nebula-cert print -path pki.cert to see the parse error","Restore pki.cert from backup or config management"],"exampleFix":"// before: hand-truncated cert file fails to marshal\n// after\nnebula-cert print -path pki.cert   # inspect failure\nnebula-cert sign -ca-crt ca.crt -ca-key ca.key -name host1 -ip 10.0.0.1/24 -out-crt pki.cert","handlingStrategy":"validation","validationCode":"// pre-parse the v1 cert to catch marshal problems early\nfunc validateV1Cert(certPEM []byte) error {\n    crt, _, err := cert.UnmarshalCertificateFromPEM(certPEM)\n    if err != nil { return err }\n    if crt.Version() == cert.Version1 {\n        if _, err := crt.MarshalForHandshakes(); err != nil { return err }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := reloadCerts(); err != nil {\n    if strings.Contains(err.Error(), \"marshalling v1 certificate\") {\n        log.Fatalf(\"pki.cert is corrupt; restore or re-issue the certificate: %v\", err)\n    }\n    return err\n}","preventionTips":["Never hand-edit PEM contents","Write pki.cert atomically (temp file + rename) to avoid truncation","Keep a known-good backup of certificates"],"tags":["pki","certificate","serialization"],"backgroundTag":"certificate-marshal-failed","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}