kubernetes/kops · error

error reading tag file %q: %v

Error message

error reading tag file %q: %v

What it means

When the cluster runs a non-default (CI/nightly) Kubernetes version, Image() downloads the component's .docker_tag file from the Kubernetes release bucket (baseURL + /bin/linux/amd64/<component>.docker_tag) over VFS. If that HTTP/VFS read fails, the error wraps the tag URL and underlying cause.

Source

Thrown at pkg/model/components/context.go:175

	// the architecture suffix.
	//
	// i.e. registry.k8s.io/kube-apiserver:v1.20.0 is a manifest list
	// and we _can_ also pull
	// registry.k8s.io/kube-apiserver-amd64:v1.20.0 directly.  But if
	// we load https://.../v1.20.0/amd64/kube-apiserver.tar then
	// the image inside that tar file is named
	// "registry.k8s.io/kube-apiserver-amd64:v1.20.0"
	imageName += "-amd64"

	baseURL := clusterSpec.KubernetesVersion
	baseURL = strings.TrimSuffix(baseURL, "/")

	tagURL := baseURL + "/bin/linux/amd64/" + component + ".docker_tag"
	klog.V(2).Infof("Downloading docker tag for %s from: %s", component, tagURL)

	b, err := vfs.Context.ReadFile(tagURL)
	if err != nil {
		return "", fmt.Errorf("error reading tag file %q: %v", tagURL, err)
	}
	tag := strings.TrimSpace(string(b))
	klog.V(2).Infof("Found tag %q for %q", tag, component)

	image := "registry.k8s.io/" + imageName + ":" + tag

	return image, nil
}

// IsCertManagerEnabled returns true if the cluster has the capability to handle cert-manager PKI
func IsCertManagerEnabled(cluster *kops.Cluster) bool {
	return cluster.Spec.CertManager != nil && fi.ValueOf(cluster.Spec.CertManager.Enabled)
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Pin clusterSpec.KubernetesVersion to a released version so a static registry.k8s.io image is used instead of downloading a tag
  2. Verify network access to the release bucket URL printed in the error (curl the tagURL)
  3. Check the kubernetesVersion string for typos or an unsupported URL form
  4. Retry later if the CI build has not been published yet

Example fix

// before
kubernetesVersion: "https://storage.googleapis.com/k8s-release-dev/ci/latest.txt"
// after
kubernetesVersion: "v1.29.4"
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: ensure the tag URL is reachable
resp, err := http.Head(tagURL)
if err != nil || resp.StatusCode != 200 {
    return fmt.Errorf("tag file not reachable: %s", tagURL)
}

Type guard

func isReleasedVersion(v string) bool { return !strings.Contains(v, "latest") && !strings.Contains(v, "ci/") }

Try / catch

b, err := vfs.Context.ReadFile(tagURL)
if err != nil {
    return "", fmt.Errorf("error reading tag file %q: %v", tagURL, err)
}
// retry transient network failures with backoff

Prevention

When it happens

Trigger: Using clusterSpec.KubernetesVersion pointing at a CI build or latest (e.g. https://storage.googleapis.com/k8s-release-dev/...) and the tag file does not exist, the URL is unreachable, or network/DNS fails during BuildOptions.

Common situations: Nightly/alpha kubernetesVersion no longer published; offline or proxied environments blocking the release bucket; typo in the version URL; bucket path scheme changes across k8s versions.

Related errors


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