router-for-me/CLIProxyAPI · error

private_key base64 decode failed: %w

Error message

private_key base64 decode failed: %w

What it means

From rebuildPEM when the extracted base64 payload (after filtering to the standard alphabet) fails base64.StdEncoding.DecodeString (keyutil.go:142-145). Even after removing whitespace and invalid characters, the remaining string is not valid base64 — typically wrong length/padding or mixed-in foreign characters that happen to be base64-legal but break the structure.

Source

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

	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 {
		case r >= 'A' && r <= 'Z':
			b.WriteRune(r)
		case r >= 'a' && r <= 'z':
			b.WriteRune(r)
		case r >= '0' && r <= '9':
			b.WriteRune(r)
		case r == '+' || r == '/' || r == '=':
			b.WriteRune(r)
		default:

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Re-copy the key from the source JSON in one shot, or re-download it from GCP
  2. Sanity-check length and padding: the base64 body length mod 4 must be 0 (ignoring final '=' padding)
  3. Avoid line-based shell edits on the private_key value

Example fix

# validate independently before feeding the proxy
jq -r .private_key sa.json | sed '1d;$d' | tr -d '\n' | base64 -d >/dev/null && echo OK || echo CORRUPT
Defensive patterns

Strategy: validation

Validate before calling

body := filterBase64(pkBetweenMarkers(pk))
if _, err := base64.StdEncoding.DecodeString(body); err != nil {
    return fmt.Errorf("PEM base64 body corrupt: %w", err)
}

Prevention

When it happens

Trigger: Base64 body with characters dropped or duplicated mid-key (still alphanumeric, so filterBase64 keeps them, but length/mod-4 is broken); padding '=' stripped; concatenated fragments of two different keys.

Common situations: Manual copy-paste that misses or duplicates a line of the base64; terminals wrapping lines into the value; sed/awk processing that deletes characters.

Related errors


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