{"record":{"id":"ed3861f763b24087","repo":"router-for-me/CLIProxyAPI","slug":"certificate-id-is-required","errorCode":null,"errorMessage":"certificate id is required","messagePattern":"certificate id is required","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/home/certificate.go","lineNumber":287,"sourceCode":"\tcase \"PRIVATE KEY\":\n\t\tkey, errParse := x509.ParsePKCS8PrivateKey(block.Bytes)\n\t\tif errParse != nil {\n\t\t\treturn nil, errParse\n\t\t}\n\t\trsaKey, ok := key.(*rsa.PrivateKey)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"client key is not rsa\")\n\t\t}\n\t\treturn rsaKey, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"client key pem type %q is unsupported\", block.Type)\n\t}\n}\n\nfunc createClientCSR(certificateID string, key *rsa.PrivateKey) ([]byte, error) {\n\tcertificateID = strings.TrimSpace(certificateID)\n\tif certificateID == \"\" {\n\t\treturn nil, fmt.Errorf(\"certificate id is required\")\n\t}\n\ttemplate := &x509.CertificateRequest{\n\t\tSubject: pkix.Name{\n\t\t\tCommonName: certificateID,\n\t\t},\n\t}\n\tder, errCreate := x509.CreateCertificateRequest(rand.Reader, template, key)\n\tif errCreate != nil {\n\t\treturn nil, errCreate\n\t}\n\treturn pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE REQUEST\", Bytes: der}), nil\n}\n\nfunc requestClientCertificate(ctx context.Context, claims homeJWTClaims, csrPEM []byte) (certificateRequestResponse, error) {\n\tvar response certificateRequestResponse\n\tif ctx == nil {\n\t\tctx = context.Background()\n\t}","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/home/certificate.go#L269-L305","documentation":"Returned by createClientCSR in internal/home/certificate.go when the certificate ID, after trimming whitespace, is empty. The CSR's CommonName is the certificate ID used by the home server to identify this client, so it is mandatory during enrollment.","triggerScenarios":"Calling the enrollment/cert-issuance flow with an empty or whitespace-only certificate ID — usually a missing or blanked id field in the enrollment config or claims.","commonSituations":"Enrollment config template left the certificate-id field empty; automation script passed an unset variable ($CERT_ID empty under set -u absent); ID was read from an env var not exported in CI.","solutions":["Set a non-empty certificate ID in the enrollment configuration/claims","If driven by a script, guard: : \"${CERT_ID:?certificate id required}\" before invoking the tool"],"exampleFix":"# before\nhome:\n  enrollment:\n    certificate-id: \"\"\n\n# after\nhome:\n  enrollment:\n    certificate-id: \"proxy-node-01\"","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(cfg.Enrollment.CertificateID) == \"\" {\n    return errors.New(\"certificate-id is required for enrollment\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In shell drivers: : \"${CERT_ID:?certificate id required}\"","Generate the ID from hostname + environment so it is never blank"],"tags":["go","enrollment","configuration","home"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}