router-for-me/CLIProxyAPI · error

home certificate response is incomplete

Error message

home certificate response is incomplete

What it means

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.

Source

Thrown at internal/home/certificate.go:162

		return nil
	}
	if errMkdir := os.MkdirAll(paths.Dir, 0o700); errMkdir != nil {
		return errMkdir
	}
	key, errKey := loadOrCreateClientKey(paths.ClientKey)
	if errKey != nil {
		return errKey
	}
	csrPEM, errCSR := createClientCSR(claims.CertificateID, key)
	if errCSR != nil {
		return errCSR
	}
	response, errRequest := requestClientCertificate(ctx, claims, csrPEM)
	if errRequest != nil {
		return errRequest
	}
	if strings.TrimSpace(response.Certificate) == "" || strings.TrimSpace(response.CA) == "" {
		return fmt.Errorf("home certificate response is incomplete")
	}
	if errVerify := verifyCACertificatePEM([]byte(response.CA), claims.CAFingerprint); errVerify != nil {
		return errVerify
	}
	if errWrite := writeFile0600(paths.ClientCert, []byte(response.Certificate)); errWrite != nil {
		return errWrite
	}
	if errWrite := writeFile0600(paths.CACert, []byte(response.CA)); errWrite != nil {
		return errWrite
	}
	return nil
}

func verifyCACertificateFile(path string, expectedFingerprint string) error {
	raw, errRead := os.ReadFile(path)
	if errRead != nil {
		return errRead
	}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Retry enrollment — transient coordinator issues (e.g. CA not ready) can produce empty payloads
  2. Check coordinator logs for why the CSR was not fulfilled (enrollment secret mismatch often surfaces here as an empty cert)
  3. Verify no intermediary proxy strips or truncates the response; call the coordinator directly if possible
  4. If it persists, re-mint the enrollment token and enroll again from a clean ~/.cli-proxy-api
Defensive patterns

Strategy: retry

Try / catch

for attempt := 1; attempt <= 3; attempt++ {
    resp, err := enroll(ctx, claims, csr)
    if err == nil && resp.Certificate != "" && resp.CA != "" {
        return resp, nil
    }
    time.Sleep(time.Duration(attempt) * 2 * time.Second) // coordinator may not be ready
}
return nil, fmt.Errorf("home certificate response is incomplete after retries")

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/2b9748a2e0cb9b1b. Report an issue: GitHub.