kubernetes/kops · error
failed to associated floating IP to instance %s: %v
Error message
failed to associated floating IP to instance %s: %v
What it means
Thrown by associateFloatingIP when the Neutron L3 floating-IP update (PUT /v2.0/floatingips/{id} setting PortID) fails while associating a floating IP with the new instance's port during RenderOpenstack. The Neutron client (l3floatingip.Update) returns errors such as port not found, IP already associated, or 401/404. The message names the instance to make the failing task identifiable in the kOps apply output.
Source
Thrown at upup/pkg/fi/cloudup/openstacktasks/instance.go:420
}
}
if changes.FloatingIP != nil {
err := associateFloatingIP(t, e)
if err != nil {
return err
}
}
return nil
}
func associateFloatingIP(t *openstack.OpenstackAPITarget, e *Instance) error {
client := t.Cloud.NetworkingClient()
_, err := l3floatingip.Update(context.TODO(), client, fi.ValueOf(e.FloatingIP.ID), l3floatingip.UpdateOpts{
PortID: e.Port.ID,
}).Extract()
if err != nil {
return fmt.Errorf("failed to associated floating IP to instance %s: %v", *e.Name, err)
}
return nil
}
func includeBootVolumeOptions(t *openstack.OpenstackAPITarget, e *Instance, opts servers.CreateOpts) (servers.CreateOpts, error) {
if !bootFromVolume(e.Metadata) {
return opts, nil
}
i, err := t.Cloud.GetImage(fi.ValueOf(e.Image))
if err != nil {
return servers.CreateOpts{}, fmt.Errorf("Error getting image information: %v", err)
}
blockDevice := servers.BlockDevice{
BootIndex: 0,
DeleteOnTermination: true,
DestinationType: "volume",View on GitHub (pinned to 4c8573c808)
Solutions
- Check the floating IP still exists and is unassociated: `openstack floating ip show <id>`; delete/recreate it and rerun `kops update cluster`
- Verify the port exists and has a fixed IP in the same subnet as the floating IP: `openstack port show <port-id>`
- Confirm Neutron credentials/RBAC allow updating floating IPs for the project
- Ensure the cluster spec doesn't reuse one floating IP for multiple instances (concurrent association conflict)
- If the cloud lacks the floating IP port-forwarding/l3 extension expected by the gophercloud version, upgrade the cloud side or pin a compatible client
Example fix
// before: stale floating IP left from failed apply // openstack floating ip delete <stale-ip-id> // after: recreate then re-apply // openstack floating ip create --subnet <subnet> <external-network> // kops update cluster --name <cluster> --yes
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: floating IP must exist, be unassociated, and port must have a fixed IP
func validateFloatingIPAssociation(netClient *gophercloud.ServiceClient, fipID, portID string) error {
fip, err := l3floatingip.Get(context.TODO(), netClient, fipID).Extract()
if err != nil {
return fmt.Errorf("floating IP %q missing: %w", fipID, err)
}
if fip.PortID != "" {
return fmt.Errorf("floating IP %q already associated with port %q", fipID, fip.PortID)
}
port, err := ports.Get(context.TODO(), netClient, portID).Extract()
if err != nil || len(port.FixedIPs) == 0 {
return fmt.Errorf("port %q missing or has no fixed IP", portID)
}
return nil
} Type guard
func isFloatingIPNotFound(err error) bool {
var _, nf gophercloud.ErrDefault404
return errors.As(err, &nf) || strings.Contains(err.Error(), "No address with that ID")
} Try / catch
_, err := l3floatingip.Update(context.TODO(), client, fi.ValueOf(e.FloatingIP.ID), l3floatingip.UpdateOpts{PortID: e.Port.ID}).Extract()
if err != nil {
if isFloatingIPNotFound(err) {
return fmt.Errorf("floating IP %s was deleted; recreate it and re-apply: %w", fi.ValueOf(e.FloatingIP.ID), err)
}
return fmt.Errorf("failed to associated floating IP to instance %s: %w", *e.Name, err)
} Prevention
- Don't share a single floating IP across multiple instances or concurrent applies
- Check with `openstack floating ip show <id>` that the IP exists and is unassociated before applying
- Ensure port and floating IP are in the same subnet/project
- Grant the automation credentials Neutron permissions to update floating IPs
- Re-run `kops update cluster` after failed applies so kOps can reconcile stale IP tasks
When it happens
Trigger: l3floatingip.Update returns error during instance creation or when changes.FloatingIP triggers re-association: FloatingIP.ID no longer exists (deleted/released between tasks), e.Port.ID is nil or points to a deleted port, the floating IP belongs to a different project/network than the port, or Neutron rejects the association because the port has no fixed IP in the floating IP's subnet.
Common situations: A leftover floating IP from a prior failed apply was deleted externally; running with insufficient Neutron RBAC to update floating IPs; port and floating IP created in mismatched subnets; concurrent applies racing to associate the same IP; Octavia/Neutron extension `l3-floating-ip` unavailable on older clouds.
Related errors
- could not establish floating network id
- GetApiIngressStatus: Failed to list floating IP's: %v
- did not find floatingsubnet for external router
- Failed to list L3 floating ip: %v
- Could not find port floatingips port=%s
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/f738a8497c658f13.
Report an issue: GitHub.