{"record":{"id":"2b9748a2e0cb9b1b","repo":"router-for-me/CLIProxyAPI","slug":"home-certificate-response-is-incomplete","errorCode":null,"errorMessage":"home certificate response is incomplete","messagePattern":"home certificate response is incomplete","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/home/certificate.go","lineNumber":162,"sourceCode":"\t\treturn nil\n\t}\n\tif errMkdir := os.MkdirAll(paths.Dir, 0o700); errMkdir != nil {\n\t\treturn errMkdir\n\t}\n\tkey, errKey := loadOrCreateClientKey(paths.ClientKey)\n\tif errKey != nil {\n\t\treturn errKey\n\t}\n\tcsrPEM, errCSR := createClientCSR(claims.CertificateID, key)\n\tif errCSR != nil {\n\t\treturn errCSR\n\t}\n\tresponse, errRequest := requestClientCertificate(ctx, claims, csrPEM)\n\tif errRequest != nil {\n\t\treturn errRequest\n\t}\n\tif strings.TrimSpace(response.Certificate) == \"\" || strings.TrimSpace(response.CA) == \"\" {\n\t\treturn fmt.Errorf(\"home certificate response is incomplete\")\n\t}\n\tif errVerify := verifyCACertificatePEM([]byte(response.CA), claims.CAFingerprint); errVerify != nil {\n\t\treturn errVerify\n\t}\n\tif errWrite := writeFile0600(paths.ClientCert, []byte(response.Certificate)); errWrite != nil {\n\t\treturn errWrite\n\t}\n\tif errWrite := writeFile0600(paths.CACert, []byte(response.CA)); errWrite != nil {\n\t\treturn errWrite\n\t}\n\treturn nil\n}\n\nfunc verifyCACertificateFile(path string, expectedFingerprint string) error {\n\traw, errRead := os.ReadFile(path)\n\tif errRead != nil {\n\t\treturn errRead\n\t}","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/home/certificate.go#L144-L180","documentation":"Thrown during fresh enrollment in internal/home/certificate.go: the coordinator's certificate response contained an empty certificate or CA field. Before this check the CSR was created and the request succeeded, so this is the server returning an incomplete payload.","triggerScenarios":"requestClientCertificate returns 200-ish but the JSON body has certificate: \"\" or ca: \"\" (or whitespace). The subsequent fingerprint verification never runs because the response fails the completeness check first.","commonSituations":"Coordinator-side failure that still returns success (CSR rejected silently, cert not yet issued, internal error mapped to an empty payload), or a proxy/load balancer in between rewriting or truncating the response body.","solutions":["Retry enrollment — transient coordinator issues (e.g. CA not ready) can produce empty payloads","Check coordinator logs for why the CSR was not fulfilled (enrollment secret mismatch often surfaces here as an empty cert)","Verify no intermediary proxy strips or truncates the response; call the coordinator directly if possible","If it persists, re-mint the enrollment token and enroll again from a clean ~/.cli-proxy-api"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt := 1; attempt <= 3; attempt++ {\n    resp, err := enroll(ctx, claims, csr)\n    if err == nil && resp.Certificate != \"\" && resp.CA != \"\" {\n        return resp, nil\n    }\n    time.Sleep(time.Duration(attempt) * 2 * time.Second) // coordinator may not be ready\n}\nreturn nil, fmt.Errorf(\"home certificate response is incomplete after retries\")","preventionTips":["Check coordinator health and enrollment-secret validity before enrolling","Ensure no intermediary proxy truncates certificate endpoints' responses","Alert on empty-payload responses at the coordinator so root causes surface there"],"tags":["mtls","certificates","enrollment","home","network"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}