kubernetes/kops · error
invalid Azure zone: %q
Error message
invalid Azure zone: %q
What it means
ZoneToLocation extracts the Azure location from a kOps zone string of the form <location>-<zone-number> (e.g. eastus-1). If splitting on "-" does not yield exactly two parts, the zone string does not match the Azure zone format and this error is returned. Callers use it to derive the region for Azure resource placement.
Source
Thrown at upup/pkg/fi/cloudup/azure/azure_utils.go:29
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package azure
import (
"fmt"
"strings"
)
// ZoneToLocation extracts the location from a zone of the
// form <location>-<available-zone-number>..
func ZoneToLocation(zone string) (string, error) {
l := strings.Split(zone, "-")
if len(l) != 2 {
return "", fmt.Errorf("invalid Azure zone: %q ", zone)
}
return l[0], nil
}
// ZoneToAvailabilityZoneNumber extracts the availability zone number from a zone of the
// form <location>-<available-zone-number>..
func ZoneToAvailabilityZoneNumber(zone string) (string, error) {
l := strings.Split(zone, "-")
if len(l) != 2 {
return "", fmt.Errorf("invalid Azure zone: %q ", zone)
}
return l[1], nil
}
// SubnetID contains the resource ID/names required to construct a subnet ID.
type SubnetID struct {
SubscriptionID string
ResourceGroupName stringView on GitHub (pinned to 4c8573c808)
Solutions
- Use zones in the format <location>-<number>, e.g. "eastus-1", "westeurope-2".
- Remove any extra "-" segments from the zone value in the cluster spec.
- Check `az account list-locations` for valid location names, then append -1/-2/-3 for availability zones.
- Run `kops edit cluster` to correct the zones field and `kops update cluster` to apply.
- For Azure regions without availability zones, ensure the chosen region supports zones before using the -N suffix.
Example fix
// before zones: ["eastus"] // after zones: ["eastus-1"]
Defensive patterns
Strategy: validation
Validate before calling
// Go: validate zone format before calling ZoneToLocation
func validAzureZone(zone string) bool {
parts := strings.Split(zone, "-")
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return false
}
_, err := strconv.Atoi(parts[1])
return err == nil
}
if !validAzureZone(zone) {
return fmt.Errorf("zone %q must be <location>-<number>, e.g. eastus-1", zone)
} Type guard
func isAzureZone(s string) bool {
l := strings.Split(s, "-")
return len(l) == 2
} Try / catch
loc, err := azure.ZoneToLocation(zone)
if err != nil {
log.Printf("zone %q invalid; expected <location>-<number> (e.g. eastus-1): %v", zone, err)
return err
} Prevention
- Always specify Azure zones as <location>-<number>, e.g. eastus-1.
- Never paste AWS zone strings (like us-east-1a) into an Azure cluster spec.
- Check region availability-zone support before adding the -N suffix.
- Lint cluster specs for the zones field before kops update.
- Use constants/enums for known-good zone values in automation.
When it happens
Trigger: Calling ZoneToLocation with a zone lacking exactly one dash-separated suffix: e.g. "eastus" (no zone number), "us-east" (multiple dashes), "eastus-1-extra", or an empty string.
Common situations: Setting kubernetesCluster zones to a region name like "eastus" instead of an availability zone "eastus-1"; copy-pasting AWS-style zones (us-east-1a has 3 parts, but note "-" split of "us-east-1a" gives 3 parts → fails); cluster spec edited by hand with invalid topology values.
Related errors
- malformed format of subnet ID: %s, %d
- failed to parse objects: %w
- --azure-subscription-id is required
- cannot parse KubernetesVersion %q in cluster: %w
- unexpected form of resource path: %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/af47531be02ac9bc.
Report an issue: GitHub.