router-for-me/CLIProxyAPI · error

home certificate request failed

Error message

home certificate request failed

What it means

Returned by the certificate-request exchange in internal/home/certificate.go: the client sent 'CERTIFICATE REQUEST <id> <secret> <csr>' over the RESP connection and received a JSON response with OK=false. The home server explicitly rejected the enrollment — the transport worked but the request was denied.

Source

Thrown at internal/home/certificate.go:330

	}
	defer func() {
		_ = conn.Close()
	}()
	if deadline, ok := dialCtx.Deadline(); ok {
		_ = conn.SetDeadline(deadline)
	}
	if _, errWrite := conn.Write(encodeRESPArray("CERTIFICATE", "REQUEST", claims.CertificateID, claims.EnrollmentSecret, string(csrPEM))); errWrite != nil {
		return response, errWrite
	}
	raw, errRead := readRESPBulk(bufio.NewReader(conn))
	if errRead != nil {
		return response, errRead
	}
	if errUnmarshal := json.Unmarshal(raw, &response); errUnmarshal != nil {
		return response, errUnmarshal
	}
	if !response.OK {
		return response, fmt.Errorf("home certificate request failed")
	}
	return response, nil
}

func encodeRESPArray(args ...string) []byte {
	var buf bytes.Buffer
	buf.WriteString("*")
	buf.WriteString(strconv.Itoa(len(args)))
	buf.WriteString("\r\n")
	for _, arg := range args {
		buf.WriteString("$")
		buf.WriteString(strconv.Itoa(len(arg)))
		buf.WriteString("\r\n")
		buf.WriteString(arg)
		buf.WriteString("\r\n")
	}
	return buf.Bytes()
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Inspect the response JSON (log it before this error is returned) for the server's reason string
  2. Regenerate/obtain a fresh enrollment secret and retry with the same certificate ID
  3. If the ID is taken, choose a new certificate ID or have the admin revoke the old entry first
  4. Verify server-side enrollment logs for the denial cause

Example fix

// before
if !response.OK {
    return response, fmt.Errorf("home certificate request failed")
}

// after (capture the server reason for diagnosis)
if !response.OK {
    return response, fmt.Errorf("home certificate request failed: ok=false error=%q", response.Error)
}
Defensive patterns

Strategy: retry

Try / catch

resp, err := requestCertificate(ctx, csrPEM)
if err != nil {
    if strings.Contains(err.Error(), "home certificate request failed") && resp.Error != "" {
        log.Errorf("enrollment denied by server: %s", resp.Error)
    }
    // retry only for transient causes (expired-then-refreshed secret), never for wrong-secret loops
}

Prevention

When it happens

Trigger: Enrollment secret wrong or expired; certificate ID already enrolled or revoked; CSR CommonName mismatch; server-side policy rejecting the request. The JSON response body often carries a reason field worth inspecting.

Common situations: Re-running enrollment with a one-time secret already consumed; secret rotated between generation and use; clock skew causing secret expiry; duplicate node ID joining the cluster.

Understand the failure class

Related errors


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