kubernetes/kops · error
SSH public key must be specified when running with Scaleway
Error message
SSH public key must be specified when running with Scaleway (create with `kops create secret --name %s sshpublickey admin -i ~/.ssh/id_rsa.pub`)
What it means
When applying a Scaleway cluster, kOps requires an SSH public key secret named 'admin' to exist. In apply_cluster.go Run, if the loaded sshPublicKeys map is empty, the apply fails with instructions on how to create the key. Scaleway provisioning injects this key into instances, so it must be present.
Solutions
- Create the key: `kops create secret --name <cluster> sshpublickey admin -i ~/.ssh/id_rsa.pub` then rerun update
- If the file is elsewhere, pass its path with -i (must be a public key, e.g. .pub file)
- Confirm with `kops get secrets` that the sshpublickey entry now exists
Example fix
// before: no ssh key secret kops create secret --name scw.example.com sshpublickey admin -i ~/.ssh/id_rsa.pub // after: key exists; kops update cluster proceeds
Defensive patterns
Strategy: validation
Validate before calling
kops get secrets --name "$CLUSTER" | grep -q sshpublickey || kops create secret --name "$CLUSTER" sshpublickey admin -i ~/.ssh/id_rsa.pub
Try / catch
if err := updateCluster(); err != nil { if strings.Contains(err.Error(), "SSH public key must be specified") { createAdminKey(); retry() } return err } Prevention
- Always run `kops create secret ... sshpublickey admin` right after `kops create cluster` for scaleway
- Script cluster bootstrap to include the key step
- Verify key presence with `kops get secrets` before updates
When it happens
Trigger: `kops update cluster` on a scaleway cluster where no 'sshpublickey admin' secret has ever been created for the cluster.
Common situations: Fresh cluster creation where the user skipped the `kops create secret` step, or after switching clusters/namespaces so the secret store for the target cluster is empty.
Related errors
- exactly one 'admin' SSH public key can be specified when…
- exactly one 'admin' SSH public key can be specified when…
- bastion is not set, but useBastion is true
- converting zone to region
- creating back-end for load-balancer
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/c4966f2254d56943.
Report an issue: GitHub.
Appendix: source
Thrown at upup/pkg/fi/cloudup/apply_cluster.go:492
case kops.CloudProviderOpenstack:
{
if len(sshPublicKeys) == 0 {
return nil, fmt.Errorf("SSH public key must be specified when running with Openstack (create with `kops create secret --name %s sshpublickey admin -i ~/.ssh/id_rsa.pub`)", cluster.ObjectMeta.Name)
}
if len(sshPublicKeys) != 1 {
return nil, fmt.Errorf("exactly one 'admin' SSH public key can be specified when running with Openstack; please delete a key using `kops delete secret`")
}
}
case kops.CloudProviderScaleway:
{
if !featureflag.Scaleway.Enabled() {
return nil, fmt.Errorf("Scaleway support is currently alpha, and is feature-gated. export KOPS_FEATURE_FLAGS=Scaleway")
}
if len(sshPublicKeys) == 0 {
return nil, fmt.Errorf("SSH public key must be specified when running with Scaleway (create with `kops create secret --name %s sshpublickey admin -i ~/.ssh/id_rsa.pub`)", cluster.ObjectMeta.Name)
}
if len(sshPublicKeys) != 1 {
return nil, fmt.Errorf("exactly one 'admin' SSH public key can be specified when running with Scaleway; please delete a key using `kops delete secret`")
}
scwCloud := cloud.(scaleway.ScwCloud)
scwZone = scwCloud.Zone()
}
case kops.CloudProviderLinode:
{
if !featureflag.Linode.Enabled() {
return nil, fmt.Errorf("Akamai (Linode) support is currently alpha, and is feature-gated. Please export KOPS_FEATURE_FLAGS=Linode")
}
}
case kops.CloudProviderMetal:
// Metal is a special case, we don't need to do anything here (yet)View on GitHub (pinned to 4c8573c808)