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
- Dump the server's Addresses (`openstack server show <id> -f json`) to see the actual addr type.
- Update parsing to handle the actual shape (use gophercloud's typed ServerAddress struct or a recursive string extraction).
- 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
- Use gophercloud's typed address structs instead of raw map[string]interface{}
- Log the full %#v of the address entry when the assertion fails
- Test parsing against the actual cloud's `openstack server show` output
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
- Type fixed did not contain addr: %v
- error building nova client: %v
- no decernable storage availability zone could be mapped to c
- error building nova client: %w
- could not delete instance %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/41ab736f5b09e529.
Report an issue: GitHub.