router-for-me/CLIProxyAPI · error

missing pem markers

Error message

missing pem markers

What it means

From rebuildPEM, the recovery path that tries to reconstruct a PEM from damaged textual input: it searches for '-----BEGIN <KIND>-----' and '-----END <KIND>-----' and fails because one or both markers are absent, or END appears before BEGIN (keyutil.go:130-136). The kind is 'RSA PRIVATE KEY' only if that string appears, otherwise 'PRIVATE KEY'.

Source

Thrown at internal/auth/vertex/keyutil.go:135

		if rsaKey, ok := key.(*rsa.PrivateKey); ok {
			der := x509.MarshalPKCS1PrivateKey(rsaKey)
			return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: der}, nil
		}
	}
	return nil, fmt.Errorf("private_key uses unsupported format")
}

func rebuildPEM(raw string) (string, error) {
	kind := "PRIVATE KEY"
	if strings.Contains(raw, "RSA PRIVATE KEY") {
		kind = "RSA PRIVATE KEY"
	}
	header := "-----BEGIN " + kind + "-----"
	footer := "-----END " + kind + "-----"
	start := strings.Index(raw, header)
	end := strings.Index(raw, footer)
	if start < 0 || end <= start {
		return "", fmt.Errorf("missing pem markers")
	}
	body := raw[start+len(header) : end]
	payload := filterBase64(body)
	if payload == "" {
		return "", fmt.Errorf("private_key base64 payload empty")
	}
	der, err := base64.StdEncoding.DecodeString(payload)
	if err != nil {
		return "", fmt.Errorf("private_key base64 decode failed: %w", err)
	}
	block := &pem.Block{Type: kind, Bytes: der}
	return string(pem.EncodeToMemory(block)), nil
}

func filterBase64(s string) string {
	var b strings.Builder
	for _, r := range s {
		switch {

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Restore the full PEM including BEGIN/END lines from the original GCP JSON file
  2. If reconstructing manually, wrap the base64 body: -----BEGIN PRIVATE KEY----- / body / -----END PRIVATE KEY----- with real newlines
  3. Re-download the service account key rather than hand-repairing it

Example fix

# before (markers lost)
MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...
# after
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...
-----END PRIVATE KEY-----
Defensive patterns

Strategy: validation

Validate before calling

if !strings.Contains(pk, "-----BEGIN") || !strings.Contains(pk, "-----END") {
    return fmt.Errorf("PEM markers missing from private_key")
}

Prevention

When it happens

Trigger: Key pasted without the BEGIN/END lines; footer missing because of truncation; only the base64 body retained; markers present for the other kind (e.g. 'RSA PRIVATE KEY' body but code looked for plain 'PRIVATE KEY' first and vice versa when only one flavor exists).

Common situations: Secret copied out of a JSON viewer that hid the header lines; CI truncating long env vars; users pasting only the 'middle' of the key assuming the rest is implied.

Related errors


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