kubernetes/kops · error

keypair is distrusted

Error message

keypair is distrusted

What it means

When an explicit keypair ID is given, promoteKeypair refuses to promote it if the keyset item carries a DistrustTimestamp — the keypair has been deliberately distrusted (e.g. via `kops distrust keypair` or automatic rotation) and can no longer be used for signing. Promoting it would reintroduce a compromised/retired credential, so the operation fails.

Source

Thrown at cmd/kops/promote_keypair.go:182

	if keypairID == "" {
		highestCandidateId := big.NewInt(0)
		for id, item := range keyset.Items {
			if item.PrivateKey != nil && item.DistrustTimestamp == nil && item.Certificate != nil {
				itemId, ok := big.NewInt(0).SetString(id, 10)
				if ok && highestCandidateId.Cmp(itemId) < 0 {
					highestCandidateId = itemId
				}
			}
		}

		keypairID = highestCandidateId.String()
		if keypairID == keyset.Primary.Id {
			fmt.Fprintf(out, "No %s keypair newer than current primary %s\n", name, keypairID)
			return nil
		}
	} else if item := keyset.Items[keypairID]; item != nil {
		if item.DistrustTimestamp != nil {
			return fmt.Errorf("keypair is distrusted")
		}
		if item.PrivateKey == nil {
			return fmt.Errorf("keypair has no private key")
		}
		if item.Certificate == nil {
			return fmt.Errorf("keypair has no certificate")
		}
	} else {
		return fmt.Errorf("keypair not found")
	}

	keyset.Primary = keyset.Items[keypairID]
	err = keyStore.StoreKeyset(ctx, name, keyset)
	if err != nil {
		return fmt.Errorf("writing keyset: %v", err)
	}

	fmt.Fprintf(out, "Promoted %s %s\n", name, keypairID)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Choose a different, still-trusted keypair ID: run `kops get keypairs <keyset>` and pick one without a DISTRUST timestamp.
  2. If no trusted newer keypair exists, issue a fresh one (`kops create keypair <keyset>` or re-run rotation) and promote that.
  3. Do not re-promote a distrusted keypair; if a rollback is truly required, investigate kOps' documented rotation-rollback procedure rather than force-promoting.
  4. Remove hardcoded keypair IDs from automation and use the implicit "promote newest" mode (omit the ID).

Example fix

// before: promotes a distrusted keypair
kops promote keypair service-account 5938372002934847 --name c.example.com
// error: keypair is distrusted
// after: list keypairs, pick a trusted one (or omit ID to auto-select newest)
kops get keypairs service-account --name c.example.com
kops promote keypair service-account --name c.example.com
Defensive patterns

Strategy: validation

Validate before calling

// shell: ensure the chosen keypair ID is not distrusted before promoting
kops get keypairs "$KEYSET" --name "$CLUSTER" --state "$KOPS_STATE_STORE" -o yaml \
  | awk -v id="$KEYPAIR_ID" '/id: /{cur=$2} /distrustTimestamp:/{d[cur]=1} END{exit !d[id]}' \
  && { echo "$KEYPAIR_ID is distrusted; choose another ID"; exit 1; } || true

Try / catch

if kops promote keypair "$KEYSET" "$KEYPAIR_ID" --name "$CLUSTER" 2>&1 | grep -q 'keypair is distrusted'; then
  echo "$KEYPAIR_ID was distrusted (rotation/compromise); issuing a fresh keypair instead"
  # select a trusted ID from kops get keypairs and retry, or omit the ID to auto-promote the newest
else
  kops promote keypair "$KEYSET" "$KEYPAIR_ID" --name "$CLUSTER"
fi

Prevention

When it happens

Trigger: `kops promote keypair <keyset> <id>` where keyset.Items[id].DistrustTimestamp != nil — i.e. the ID was previously distrusted with `kops distrust keypair` or distrusted during a completed rotation.

Common situations: Trying to roll back a rotation by re-promoting an old, already-distrusted keypair; scripting promotion with a hardcoded ID captured before the keypair was distrusted; recovering from a bad rotation by re-enabling a retired cert (which kOps blocks for safety).

Related errors


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