kubernetes/kops · error

unknown arch for CNI plugin binaries asset: %s

Error message

unknown arch for CNI plugin binaries asset: %s

What it means

When no env-var override is set, FindCNIAssets selects a default CNI plugin URL by CPU architecture via a switch on architectures.Architecture (amd64/arm64 only). This error is returned for any other architecture value, meaning kOps has no default CNI plugin binaries defined for that platform.

Source

Thrown at pkg/nodemodel/wellknownassets/cni.go:105

			cniAssetURL = defaultCNIAssetAmd64K8s_35
		case ig.KubernetesVersion().IsGTE("1.34"):
			cniAssetURL = defaultCNIAssetAmd64K8s_34
		case ig.KubernetesVersion().IsGTE("1.32"):
			cniAssetURL = defaultCNIAssetAmd64K8s_32
		}
	case architectures.ArchitectureArm64:
		switch {
		case ig.KubernetesVersion().IsGTE("1.36"):
			cniAssetURL = defaultCNIAssetArm64K8s_36
		case ig.KubernetesVersion().IsGTE("1.35"):
			cniAssetURL = defaultCNIAssetArm64K8s_35
		case ig.KubernetesVersion().IsGTE("1.34"):
			cniAssetURL = defaultCNIAssetArm64K8s_34
		case ig.KubernetesVersion().IsGTE("1.32"):
			cniAssetURL = defaultCNIAssetArm64K8s_32
		}
	default:
		return nil, fmt.Errorf("unknown arch for CNI plugin binaries asset: %s", arch)
	}

	if cniAssetURL == "" {
		return nil, fmt.Errorf("unknown CNI plugin binaries asset: %s", arch)
	} else {
		klog.V(2).Infof("Adding CNI plugin binaries asset: %s", cniAssetURL)
	}

	u, err := url.Parse(cniAssetURL)
	if err != nil {
		return nil, fmt.Errorf("unable to parse CNI plugin binaries asset URL %q: %v", cniAssetURL, err)
	}

	asset, err := assetBuilder.RemapFile(u, nil)
	if err != nil {
		return nil, fmt.Errorf("unable to remap CNI plugin binaries asset: %v", err)
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use a supported architecture: ensure instance groups/machine types resolve to amd64 or arm64
  2. Set CNI_VERSION_URL and CNI_ASSET_HASH_STRING env vars to explicitly supply a CNI asset for your platform, bypassing the arch switch
  3. If calling FindCNIAssets directly from code, pass architectures.ArchitectureAmd64 or ArchitectureArm64
  4. Check for typos or unexported/zero-value Architecture values in custom tooling

Example fix

// before
arch := architectures.Architecture("i386")
// after
arch := architectures.ArchitectureAmd64
Defensive patterns

Strategy: type-guard

Validate before calling

if arch != architectures.ArchitectureAmd64 && arch != architectures.ArchitectureArm64 {
    return fmt.Errorf("CNI assets only supported for amd64/arm64, got %s", arch)
}

Type guard

func isSupportedArch(a architectures.Architecture) bool {
    return a == architectures.ArchitectureAmd64 || a == architectures.ArchitectureArm64
}

Try / catch

if !isSupportedArch(arch) {
    return fmt.Errorf("unsupported arch %s for CNI assets; set CNI_VERSION_URL/CNI_ASSET_HASH_STRING to override", arch)
}
asset, err := FindCNIAssets(ig, assetBuilder, arch)

Prevention

When it happens

Trigger: FindCNIAssets is called (via BuildKubernetesFileAssets) with arch set to a value other than ArchitectureAmd64 or ArchitectureArm64 — no env override present, so the switch hits its default branch.

Common situations: Building for a 32-bit or exotic platform; a custom kOps build/fork passing an incorrectly initialized Architecture value; code changes that map machine types to an unsupported arch.

Related errors


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