kubernetes/kubernetes · error
failed to init kubernetes.io/legacy-unknown certificate cont
Error message
failed to init kubernetes.io/legacy-unknown certificate controller: %w
What it means
When the legacy-unknown signer files are configured, signer.NewLegacyUnknownCSRSigningController builds the signer that signs CSRs of type kubernetes.io/legacy-unknown. A returned error aborts construction of the CSR signing controller.
Source
Thrown at cmd/kube-controller-manager/app/certificates.go:117
}
if kubeAPIServerSignerCertFile, kubeAPIServerSignerKeyFile := getKubeAPIServerClientSignerFiles(controllerContext.ComponentConfig.CSRSigningController); len(kubeAPIServerSignerCertFile) > 0 || len(kubeAPIServerSignerKeyFile) > 0 {
kubeAPIServerClientSigner, err := signer.NewKubeAPIServerClientCSRSigningController(ctx, c, csrInformer, kubeAPIServerSignerCertFile, kubeAPIServerSignerKeyFile, certTTL)
if err != nil {
return nil, fmt.Errorf("failed to init kubernetes.io/kube-apiserver-client certificate controller: %w", err)
}
rx = append(rx, func(ctx context.Context) {
kubeAPIServerClientSigner.Run(ctx, 5)
})
} else {
logger.Info("Skipping CSR signer controller because specific files were specified for other signers and not this one", "controller", "kubernetes.io/kube-apiserver-client")
}
if legacyUnknownSignerCertFile, legacyUnknownSignerKeyFile := getLegacyUnknownSignerFiles(controllerContext.ComponentConfig.CSRSigningController); len(legacyUnknownSignerCertFile) > 0 || len(legacyUnknownSignerKeyFile) > 0 {
legacyUnknownSigner, err := signer.NewLegacyUnknownCSRSigningController(ctx, c, csrInformer, legacyUnknownSignerCertFile, legacyUnknownSignerKeyFile, certTTL)
if err != nil {
return nil, fmt.Errorf("failed to init kubernetes.io/legacy-unknown certificate controller: %w", err)
}
rx = append(rx, func(ctx context.Context) {
legacyUnknownSigner.Run(ctx, 5)
})
} else {
logger.Info("Skipping CSR signer controller because specific files were specified for other signers and not this one", "controller", "kubernetes.io/legacy-unknown")
}
return newControllerLoop(concurrentRun(rx...), controllerName), nil
}
func areKubeletServingSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool {
// if only one is specified, it will error later during construction
return len(config.KubeletServingSignerConfiguration.CertFile) > 0 || len(config.KubeletServingSignerConfiguration.KeyFile) > 0
}
func areKubeletClientSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool {
// if only one is specified, it will error later during constructionView on GitHub (pinned to b882c60b40)
Solutions
- Verify the legacy-unknown signing cert and key files exist and are readable.
- Confirm the cert/key pair matches (compare modulus).
- Read the wrapped %w for the specific TLS error.
- Consider whether you need the legacy-unknown signer at all (deprecated); remove its flags if unused.
Defensive patterns
Strategy: validation
Validate before calling
# Pre-flight: validate the legacy-unknown signing pair (and consider removing it).
CERT=/etc/kubernetes/pki/legacy-unknown-ca.crt # --cluster-signing-legacy-unknown-cert-file
KEY=/etc/kubernetes/pki/legacy-unknown-ca.key # --cluster-signing-legacy-unknown-key-file
openssl x509 -in "$CERT" -noout >/dev/null 2>&1 || { echo "bad cert" >&2; exit 1; }
openssl rsa -in "$KEY" -noout >/dev/null 2>&1 || { echo "bad key" >&2; exit 1; }
[ "$(openssl x509 -in "$CERT" -noout -modulus | openssl md5)" = "$(openssl rsa -in "$KEY" -noout -modulus | openssl md5)" ] \
|| { echo "cert/key mismatch" >&2; exit 1; } Try / catch
signer, err := signer.NewLegacyUnknownCSRSigningController(ctx, c, csrInformer, certFile, keyFile, certTTL)
if err != nil {
return nil, fmt.Errorf("failed to init kubernetes.io/legacy-unknown certificate controller: %w", err)
} Prevention
- The legacy-unknown signer is deprecated; remove its flags unless explicitly needed.
- Deploy cert and key as an atomic pair with a modulus compare.
- Keep file permissions correct for the controller-manager uid.
When it happens
Trigger: certificates.go:115 calls signer.NewLegacyUnknownCSRSigningController(ctx, c, csrInformer, certFile, keyFile, certTTL). It errors when the cert/key pair cannot be loaded/parsed, the pair does not match, or the files are unreadable.
Common situations: Misconfigured --cluster-signing-legacy-unknown-cert-file/--cluster-signing-legacy-unknown-key-file (or default pair) with missing/unreadable/mismatched files. The legacy-unknown signer is largely deprecated, so misconfiguration often comes from stale guides. PEM corruption, permission errors.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to init kubernetes.io/kubelet-serving certificate con
- failed to init kubernetes.io/kube-apiserver-client-kubelet c
- failed to init kubernetes.io/kube-apiserver-client certifica
- cannot specify default and per controller certs at the same
- %q: %v
AI-assisted analysis of kubernetes/kubernetes@b882c60b40 (2026-08-07).
Data as JSON: /api/errors/2c5010390f6dbcb0.
Report an issue: GitHub.