kubernetes/kops · error

client certificate chain does not match universe ID

Error message

client certificate chain does not match universe ID

What it means

After the cert chain verifies cryptographically, AuthenticateClientToUniverse requires the universe ID to match at least one certificate in the verified chain (typically the root CA). No chain contained a certificate whose identity equals the universe ID, so the client is not a member of this universe and authentication is rejected.

Source

Thrown at discovery/pkg/discovery/auth.go:85

		}
		verifiedChains = chains
	}

	// The universe ID must match at least one of the certificates in the chain (typically the root CA).
	var matchingChain []*x509.Certificate
	for _, verifiedChain := range verifiedChains {
		for _, cert := range verifiedChain {
			hash := sha256.Sum256(cert.RawSubjectPublicKeyInfo)
			calculatedUniverseID := hex.EncodeToString(hash[:])
			if calculatedUniverseID == universeID {
				matchingChain = verifiedChain
				break
			}
		}
	}

	if matchingChain == nil {
		return nil, fmt.Errorf("client certificate chain does not match universe ID")
	}

	clientID := matchingChain[0].Subject.CommonName
	if clientID == "" {
		return nil, fmt.Errorf("client certificate missing Common Name")
	}

	return &UserInfo{
		UniverseID: universeID,
		ClientID:   clientID,
	}, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Issue the client a certificate signed by the CA whose identity (subject) matches the target universeID.
  2. Verify the universeID passed to AuthenticateClientToUniverse matches the universe the cert was issued for.
  3. Re-provision or re-issue client credentials after a universe/cluster rebuild so the root CA matches.

Example fix

// before: cert from universe-a presented to universe-b
AuthenticateClientToUniverse(ctx, universeBID, tlsConn)
// after: use credentials issued for the target universe
AuthenticateClientToUniverse(ctx, universeBID, connWithUniverseBCert)
Defensive patterns

Strategy: validation

Validate before calling

func certMatchesUniverse(chain []*x509.Certificate, universeID string) bool {
	for _, c := range chain {
		if c.Subject.CommonName == universeID || c.Subject.Organization[0] == universeID {
			return true
		}
	}
	return false
}
// call before authenticating
if !certMatchesUniverse(peerCertificates, universeID) { /* reject early */ }

Type guard

func isUniverseCert(cert *x509.Certificate, universeID string) bool {
	return cert != nil && (cert.Subject.CommonName == universeID || slices.Contains(cert.Subject.Organization, universeID))
}

Prevention

When it happens

Trigger: Calling AuthenticateClientToUniverse with a certificate chain that verifies against a valid CA but whose chain contains no certificate matching the expected universeID (e.g. wrong universe's cert presented).

Common situations: Client configured with credentials from a different cluster/universe; server's expected universeID changed after a re-provision; stale or copied kubeconfig/cert bundle pointing at another universe.

Understand the failure class

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/8142c9879e03cd8c. Report an issue: GitHub.