rancher/rancher · error
secret [%s] must be of type [%s] or [%s] or [%s]
Error message
secret [%s] must be of type [%s] or [%s] or [%s]
What it means
Thrown by the RKE2/K3s cluster planner while generating containerd registry configuration. A registry entry in RKEControlPlane.spec.rkeConfig.registries points at a secret via authConfigSecretName, and the secret was found but its .type is not one of the three accepted types: rke.cattle.io/auth-config (rkev1.AuthConfigSecretType), kubernetes.io/basic-auth, or kubernetes.io/dockerconfigjson. The planner refuses to build the auth block from any other secret type, so control-plane provisioning stops.
Source
Thrown at pkg/capr/planner/registry.go:85
registryConfig.TLS.KeyFile = file.Path
files = append(files, file)
}
}
if len(config.CABundle) > 0 {
file := toFile(controlPlane, fmt.Sprintf("tls/registries/%s/ca.crt", registryName), config.CABundle)
registryConfig.TLS.CAFile = file.Path
files = append(files, file)
}
if config.AuthConfigSecretName != "" {
secret, err := p.secretCache.Get(controlPlane.Namespace, config.AuthConfigSecretName)
if err != nil {
return data, err
}
if secret.Type != rkev1.AuthConfigSecretType && secret.Type != corev1.SecretTypeBasicAuth && secret.Type != corev1.SecretTypeDockerConfigJson {
return data, fmt.Errorf("secret [%s] must be of type [%s] or [%s] or [%s]",
config.AuthConfigSecretName, rkev1.AuthConfigSecretType, corev1.SecretTypeBasicAuth, corev1.SecretTypeDockerConfigJson)
}
if secret.Data == nil {
return data, fmt.Errorf("secret [%s] has nil data", config.AuthConfigSecretName)
}
username := string(secret.Data[rkev1.UsernameAuthConfigSecretKey])
password := string(secret.Data[rkev1.PasswordAuthConfigSecretKey])
// we need to re-encode the auth block for containerd to leverage it properly.
// The secret cache automatically decodes data values for us to make them easier to work with,
// but containerd will refuse to work with an unencoded auth block.
auth := base64.StdEncoding.EncodeToString(secret.Data[rkev1.AuthAuthConfigSecretKey])
identityToken := string(secret.Data[rkev1.IdentityTokenAuthConfigSecretKey])
// need to pull out the username, password, auth, from the .dockerconfigjson key
if secret.Type == corev1.SecretTypeDockerConfigJson {
username, password, auth, err = cluster.UnwrapDockerConfigJson(registryName, secret.Data)View on GitHub (pinned to 932558d4e6)
Solutions
- Recreate the secret with an accepted type: kubectl -n <cluster-ns> create secret generic reg-auth --type=kubernetes.io/basic-auth --from-literal=username=<user> --from-literal=password=<pass>
- Or use a docker-config secret: kubectl -n <cluster-ns> create secret docker-registry reg-auth --docker-server=<registry> --docker-username=<user> --docker-password=<pass>
- Or patch the type in place: kubectl -n <cluster-ns> patch secret reg-auth -p '{"type":"kubernetes.io/basic-auth"}'
- Verify the value of authConfigSecretName in the control plane's rkeConfig matches the intended secret in the same namespace as the RKEControlPlane object
Example fix
# before apiVersion: v1 kind: Secret metadata: name: reg-auth namespace: c-m-xxxxx # no type -> Opaque -> error 620 # after type: kubernetes.io/basic-auth stringData: username: myuser password: mypass
Defensive patterns
Strategy: validation
Validate before calling
// Before setting authConfigSecretName, verify the secret type
const (
TypeAuthConfig = "rke.cattle.io/auth-config"
TypeBasicAuth = "kubernetes.io/basic-auth"
TypeDockerJSON = "kubernetes.io/dockerconfigjson"
)
func validRegistryAuthSecret(s *corev1.Secret) bool {
if s == nil {
return false
}
return s.Type == TypeAuthConfig || s.Type == TypeBasicAuth || s.Type == TypeDockerJSON
}
// secret, err := secretCache.Get(cp.Namespace, cfg.AuthConfigSecretName)
// if err == nil && !validRegistryAuthSecret(secret) { /* fix secret before applying rkeConfig */ } Type guard
func isRegistryAuthSecret(s *corev1.Secret) bool {
switch s.GetType() {
case "rke.cattle.io/auth-config", "kubernetes.io/basic-auth", "kubernetes.io/dockerconfigjson":
return true
}
return false
} Try / catch
err := reconcileRegistries(...) // planner call
if err != nil {
if strings.Contains(err.Error(), "must be of type") {
// secret-type problem: recreate the secret with basic-auth/dockerconfigjson type, then requeue
}
return err
} Prevention
- Always create registry auth secrets with kubectl create secret docker-registry or --type=kubernetes.io/basic-auth, never bare generic secrets
- Add admission-time policy (Kyverno/OPA) requiring one of the three accepted types for secrets referenced as registry auth
- Add a lint step in CI for RKEControlPlane manifests that resolves authConfigSecretName and asserts the secret type
When it happens
Trigger: Setting spec.rkeConfig.registries.<name>.authConfigSecretName (or the mirrors section) on an RKEControlPlane to a secret created without an explicit type. Example: kubectl create secret generic reg-auth --from-literal=username=... --from-literal=password=... produces type Opaque, which fails this check during plan generation.
Common situations: Users create the registry auth secret with 'create secret generic' (defaults to Opaque) instead of basic-auth or docker-registry; a secret was recreated after a rename and lost its --type flag; docs or automation scripts that predate this type check; the name resolves to a different, unrelated secret in the control-plane namespace.
Related errors
- secret [%s] has nil data
- error getting secret for %s : %w
- error getting secret %s: %w
- getting access token for user: %w
- invalid data for auth store update
AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16).
Data as JSON: /api/errors/6dbe47cd7118327d.
Report an issue: GitHub.