kubernetes/kops · error

host %v did not have spec.instanceGroup

Error message

host %v did not have spec.instanceGroup

What it means

The Host object exists and has a public key, but spec.instanceGroup is empty. The verifier needs the instance group to include in the VerifyResult (used later for authorization of what certificates/roles the node may receive), so it rejects the request.

Source

Thrown at pkg/bootstrap/pkibootstrap/pkiverifier/verifier.go:153

		Namespace: "kops-system",
		Name:      nodeName,
	}
	var host kops.Host
	if err := v.client.Get(ctx, id, &host); err != nil {
		if apierrors.IsNotFound(err) {
			return nil, nil, fmt.Errorf("host not found for %v", id)
		}
		return nil, nil, fmt.Errorf("error getting host %v: %w", id, err)
	}

	// TODO: Check instance-group matches request (does it matter?)

	if host.Spec.PublicKey == "" {
		return nil, nil, fmt.Errorf("host %v did not have public-key", id)
	}
	instanceGroup := host.Spec.InstanceGroup
	if instanceGroup == "" {
		return nil, nil, fmt.Errorf("host %v did not have spec.instanceGroup", id)
	}
	pubKey, err := pki.ParsePEMPublicKey([]byte(host.Spec.PublicKey))
	if err != nil {
		return nil, nil, fmt.Errorf("failed to parse public key: %w", err)
	}

	var sans []string

	result := &bootstrap.VerifyResult{
		NodeName:          nodeName,
		InstanceGroupName: instanceGroup,
		CertificateNames:  sans,
	}

	return result, pubKey.Key, nil
}

func verifySignature(signingKey crypto.PublicKey, payload []byte, signature []byte) bool {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set spec.instanceGroup on the Host to the node's actual instance group (e.g. nodes, master-az1) and retry bootstrap
  2. Check kubectl get host <name> -n kops-system -o yaml to see whether the field was dropped by validation or automation
  3. Fix the tooling that creates Host objects so it always sets instanceGroup
  4. Confirm you are on a kops version whose Host CRD contains the instanceGroup field

Example fix

// before
// spec:
//   publicKey: ...

// after
// spec:
//   publicKey: ...
//   instanceGroup: nodes
Defensive patterns

Strategy: validation

Validate before calling

var host kops.Host
if err := c.Get(ctx, types.NamespacedName{Namespace: "kops-system", Name: nodeName}, &host); err != nil {
    return err
}
if host.Spec.InstanceGroup == "" {
    return fmt.Errorf("Host %s must have spec.instanceGroup set before bootstrap", nodeName)
}

Type guard

func hostHasInstanceGroup(h *kops.Host) bool {
    return h != nil && strings.TrimSpace(h.Spec.InstanceGroup) != ""
}

Try / catch

result, err := verifier.VerifyToken(ctx, req, token, body)
if err != nil {
    if strings.Contains(err.Error(), "did not have spec.instanceGroup") {
        return fmt.Errorf("set Host spec.instanceGroup for %s and retry", nodeName)
    }
    return err
}

Prevention

When it happens

Trigger: VerifyToken -> getSigningKey fetches a Host where host.Spec.InstanceGroup == "" — the Host manifest omitted spec.instanceGroup or the reconciling controller never populated it.

Common situations: Manually authored Host YAML missing the instanceGroup field; copy of Host from a different cluster/version where the field was named differently; automation bug creating Hosts before group assignment; CRD schema change between kops versions dropping the value.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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