k3s-io/k3s · error

cannot enable secrets encryption with %s key type, no keys f

Error message

cannot enable secrets encryption with %s key type, no keys found

What it means

Enabling secrets encryption switches the first provider from identity to a real cipher (aescbc or secretbox) chosen by --encrypt-provider / the EncryptProvider config. The existing key material in the keys file must already contain at least one key of that cipher type; k3s scans the remaining providers for a matching block and fails this check when none exists, because it never auto-generates keys on the enable path.

Source

Thrown at pkg/server/handlers/secrets-encrypt.go:177

		logrus.Infoln("Disabling secrets encryption")
		if err := secretsencrypt.WriteEncryptionConfig(control.Runtime, curKeys, control.EncryptProvider, enable); err != nil {
			return err
		}
	} else if !enable {
		logrus.Infoln("Secrets encryption already disabled")
		return nil
	} else if providers[0].Identity != nil && (providers[1].AESCBC != nil || providers[1].Secretbox != nil) && enable {
		foundKey := false
		// Check the rest of the providers (generally 2nd and 3rd) for the key type we are trying to enable.
		// If we find one, we can proceed.
		for _, p := range providers[1:] {
			if (control.EncryptProvider == secretsencrypt.AESCBCProvider && p.AESCBC != nil) ||
				(control.EncryptProvider == secretsencrypt.SecretBoxProvider && p.Secretbox != nil) {
				foundKey = true
			}
		}
		if !foundKey {
			return fmt.Errorf("cannot enable secrets encryption with %s key type, no keys found", control.EncryptProvider)
		}
		logrus.Infoln("Enabling secrets encryption")
		if err := secretsencrypt.WriteEncryptionConfig(control.Runtime, curKeys, control.EncryptProvider, enable); err != nil {
			return err
		}
	} else if enable {
		logrus.Infoln("Secrets encryption already enabled")
		return nil
	} else {
		return errors.New("unable to enable/disable secrets encryption, unknown configuration")
	}
	if err := cluster.Save(ctx, control, true); err != nil {
		return err
	}
	return reencryptAndRemoveKey(ctx, control, true, os.Getenv("NODE_NAME"))
}

func EncryptionConfig(ctx context.Context, control *config.Control) http.Handler {

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Generate keys for the desired cipher first: set the provider, run 'k3s secrets-encrypt rotate-keys', then run enable.
  2. If you meant to use the cipher whose keys already exist, enable with that provider name (aescbc vs secretbox) instead.
  3. Verify the keys file under /var/lib/rancher/k3s/server/cred/ contains entries for the requested provider before enabling.
  4. If keys were lost, restore the cred directory from backup before attempting enable.

Example fix

# before
k3s secrets-encrypt enable --secretbox  # only aescbc keys exist -> error

# after
k3s secrets-encrypt rotate-keys --old-cipher aescbc  # then
k3s secrets-encrypt enable --secretbox
Defensive patterns

Strategy: validation

Validate before calling

// Before enable --secretbox: confirm keys of that cipher exist in the keys file
keys, _ := secretsencrypt.GetEncryptionKeys(runtime)
hasType := false
for _, k := range keys { if k.Type == "secretbox" { hasType = true } }
if !hasType { log.Fatal("run rotate-keys first to generate secretbox keys") }

Prevention

When it happens

Trigger: 'k3s secrets-encrypt enable --secretbox' when the encryption keys file only holds aescbc keys (or vice versa), or enabling with a provider whose key entries were deleted from the cred/keys file.

Common situations: Clusters created before secrets encryption was turned on whose default provider keys were generated for a different cipher; admins switching EncryptProvider between aescbc and secretbox without first rotating keys; key files pruned or restored from an old backup.

Related errors


AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15). Data as JSON: /api/errors/1e90d052d5602e42. Report an issue: GitHub.