kubernetes/kops · error
unexpected number of network interfaces for instance %q: %v
Error message
unexpected number of network interfaces for instance %q: %v
What it means
In Reconcile, the controller looks up the network interface(s) attached to the node's EC2 instance via DescribeNetworkInterfaces with an attachment.instance-id filter, and expects exactly one attached ENI. This error is thrown when the API returns zero or more than one interface, meaning the single-ENI assumption behind the IPv6 prefix delegation logic is violated.
Source
Thrown at cmd/kops-controller/controllers/awsipam.go:137
return ctrl.Result{}, err
}
instanceID := strings.Split(providerURL.Path, "/")[2]
eni, err := r.ec2Client.DescribeNetworkInterfaces(ctx, &ec2.DescribeNetworkInterfacesInput{
Filters: []ec2types.Filter{
{
Name: new("attachment.instance-id"),
Values: []string{
instanceID,
},
},
},
})
if err != nil {
return ctrl.Result{}, err
}
if len(eni.NetworkInterfaces) != 1 {
return ctrl.Result{}, fmt.Errorf("unexpected number of network interfaces for instance %q: %v", instanceID, len(eni.NetworkInterfaces))
}
if len(eni.NetworkInterfaces[0].Ipv6Prefixes) != 1 {
return ctrl.Result{}, fmt.Errorf("unexpected amount of ipv6 prefixes on interface %q: %v", *eni.NetworkInterfaces[0].NetworkInterfaceId, len(eni.NetworkInterfaces[0].Ipv6Prefixes))
}
ipv6Address := aws.ToString(eni.NetworkInterfaces[0].Ipv6Prefixes[0].Ipv6Prefix)
podCIDRs := []string{ipv6Address}
if err := patchNodePodCIDRs(r.coreV1Client, ctx, node, podCIDRs); err != nil {
return ctrl.Result{}, err
}
}
return ctrl.Result{}, nil
}
func (r *AWSIPAMReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).View on GitHub (pinned to 4c8573c808)
Solutions
- Detach extra network interfaces from the instance so only the primary ENI remains attached.
- Verify node.Spec.ProviderID encodes the correct instance ID (format aws:///<zone>/<i-...>) and that the instance still exists in EC2.
- If the node legitimately needs multiple ENIs, do not use this IPv6-prefix IPAM controller; assign podCIDRs another way (e.g. cloud-controller-manager or static cluster config).
- Re-check after a short delay — transient states during instance launch/termination can briefly return an unexpected interface count; rely on controller-runtime requeue/backoff.
Example fix
// before
if len(eni.NetworkInterfaces) != 1 {
return ctrl.Result{}, fmt.Errorf("unexpected number of network interfaces for instance %q: %v", instanceID, len(eni.NetworkInterfaces))
}
// after
if len(eni.NetworkInterfaces) == 0 {
klog.Warningf("no network interfaces yet for instance %q; requeueing", instanceID)
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
}
if len(eni.NetworkInterfaces) > 1 {
return ctrl.Result{}, fmt.Errorf("unexpected number of network interfaces for instance %q: %v", instanceID, len(eni.NetworkInterfaces))
} Defensive patterns
Strategy: validation
Validate before calling
resp, err := ec2Client.DescribeInstances(ctx, &ec2.DescribeInstancesInput{
InstanceIds: []string{instanceID},
})
if err != nil || len(resp.Reservations) == 0 {
return fmt.Errorf("instance %s not found or describe failed", instanceID)
}
// only proceed when the instance has exactly one attached ENI
Type guard
func singleENI(eni *ec2.DescribeNetworkInterfacesOutput) bool {
return eni != nil && len(eni.NetworkInterfaces) == 1
} Try / catch
result, err := r.Reconcile(ctx, req)
if err != nil && strings.Contains(err.Error(), "unexpected number of network interfaces") {
// log and alert instead of hot-looping; do not requeue immediately
klog.Errorf("instance topology not single-ENI: %v", err)
return ctrl.Result{}, nil
} Prevention
- Keep nodes single-ENI: avoid attaching extra ENIs (EFA, multi-homed workloads) to nodes managed by this IPAM controller.
- Validate ProviderID format (aws:///<zone>/<i-id>) when nodes register, so the instance-id filter never matches a wrong/stale ID.
- Confirm the node instance still exists in EC2 before treating 0 interfaces as fatal.
- Monitor for this error as a signal that another controller (CNI, LB) is attaching ENIs to nodes.
When it happens
Trigger: DescribeNetworkInterfaces(attachment.instance-id == instanceID) returns len(NetworkInterfaces) != 1: the instance has additional attached ENIs (multi-NI instance, CNI-chained ENIs, load-balancer or EFA attachments), the filter matched the primary ENI of another role, or it matched none because the instance was terminated or the ProviderID-encoded instance ID is wrong.
Common situations: Nodes with extra ENIs attached for storage, monitoring, or EFA workloads; a malformed ProviderID like aws:///zone/<wrong-id> after node replacement; a stale/terminated instance id queried before EC2 state propagates; clusters where the AWS CNI or another controller attaches secondary ENIs to nodes.
Related errors
- unexpected amount of ipv6 prefixes on interface %q: %v
- error deleting EgressOnlyInternetGateway %q: %v
- error listing EgressOnlyInternetGateway: %v
- error deleting ENI %q: %v
- error listing ENIs: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/4046e2f285a16048.
Report an issue: GitHub.