kubernetes/kops · error

Fixed IP was not a string: %v

Error message

Fixed IP was not a string: %v

What it means

Thrown by GetServerFixedIP when a server address entry of type 'fixed' contains an 'addr' key whose value is not a JSON string. Nova address maps are loosely typed interface{} values; a non-string addr breaks the string type assertion used to extract the pool IP.

Source

Thrown at upup/pkg/fi/cloudup/openstack/utils.go:116

		return "", fmt.Errorf("unhandled role %q", ig.Spec.Role)
	}
	if len(candidates) == 0 {
		return "", fmt.Errorf("No suitable flavor for role %q", ig.Spec.Role)
	}
	return candidates[0].Name, nil
}

func GetServerFixedIP(server *servers.Server, interfaceName string) (poolAddress string, err error) {
	if localAddr, ok := server.Addresses[interfaceName]; ok {
		if localAddresses, ok := localAddr.([]interface{}); ok {
			for _, addr := range localAddresses {
				addrMap := addr.(map[string]interface{})
				if addrType, ok := addrMap[openstackExternalIPType]; ok && addrType == openstackAddressFixed {
					if fixedIP, ok := addrMap[openstackAddress]; ok {
						if fixedIPStr, ok := fixedIP.(string); ok {
							poolAddress = fixedIPStr
						} else {
							err = fmt.Errorf("Fixed IP was not a string: %v", fixedIP)
						}
					} else {
						err = fmt.Errorf("Type fixed did not contain addr: %v", addr)
					}
				}
			}
		}
	} else {
		err = fmt.Errorf("server `%s` interface name `%s` not found", server.ID, interfaceName)
	}
	return poolAddress, err
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Dump the server's Addresses (`openstack server show <id> -f json`) to see the actual addr type.
  2. Update parsing to handle the actual shape (use gophercloud's typed ServerAddress struct or a recursive string extraction).
  3. Verify the network uses standard fixed IP assignment; report nonstandard formats to the cloud provider.

Example fix

// before
if fixedIPStr, ok := fixedIP.(string); ok {
    poolAddress = fixedIPStr
} else {
    err = fmt.Errorf("Fixed IP was not a string: %v", fixedIP)
}
// after
switch v := fixedIP.(type) {
case string:
    poolAddress = v
case map[string]interface{}:
    if s, ok := v["addr"].(string); ok {
        poolAddress = s
    }
default:
    err = fmt.Errorf("Fixed IP was not a string: %T %v", fixedIP, fixedIP)
}
Defensive patterns

Strategy: type-guard

Type guard

func fixedIPString(v interface{}) (string, bool) {
    switch s := v.(type) {
    case string:
        return s, true
    case map[string]interface{}:
        a, ok := s["addr"]
        if !ok {
            return "", false
        }
        return fixedIPString(a)
    }
    return "", false
}

Try / catch

if ip, ok := fixedIPString(fixedIP); ok {
    poolAddress = ip
} else {
    err = fmt.Errorf("Fixed IP was not a string: %T %v", fixedIP, fixedIP)
}

Prevention

When it happens

Trigger: GetServerFixedIP (called by osBuildCloudInstanceGroup) walks server.Addresses[interfaceName], finds a fixed-type entry, gets addrMap[openstackAddress], but `fixedIP.(string)` fails — the addr value is a number, object, or other non-string type.

Common situations: Custom Neutron/SDN address extensions returning structured address objects; clouds with unusual address formats; future API changes where addr becomes an object; corrupted or mocked server payloads.

Related errors


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