kubernetes/kops · error

file url is not defined

Error message

file url is not defined

What it means

findHash requires a URL to look up the file's hash: it uses DownloadURL (or CanonicalURL when getAssets is set). If the FileAsset has neither URL set, hashing is impossible, so it fails with this message.

Source

Thrown at pkg/assets/builder.go:378

	// If the phase is "assets" we use the CanonicalFileURL,
	// but during other phases we use the hash from the FileRepository or the base kops path.
	// We do not want to just test for CanonicalFileURL as it is defined in
	// other phases, but is not used to test for the SHA.
	// This prevents a chicken and egg problem where the file is not yet in the FileRepository.
	//
	// assets phase -> get the sha file from the source / CanonicalFileURL
	// any other phase -> get the sha file from the kops base location or the FileRepository
	//
	// TLDR; we use the file.CanonicalFileURL during assets phase, and use file.FileUrl the
	// rest of the time. If not we get a chicken and the egg problem where we are reading the sha file
	// before it exists.
	u := file.DownloadURL
	if a.getAssets {
		u = file.CanonicalURL
	}

	if u == nil {
		return nil, fmt.Errorf("file url is not defined")
	}

	knownHash, found, err := assetdata.GetHash(file.CanonicalURL)
	if err != nil {
		return nil, err
	}
	if found {
		return knownHash, nil
	}

	if cachedHash, found := downloadedFileHashes.Load(u.String()); found {
		klog.V(8).Infof("using cached hash for %q", u)
		return cachedHash.(*hashing.Hash), nil
	}

	klog.V(2).Infof("asset %q is not well-known, downloading hash", file.CanonicalURL)

	// We now prefer sha256 hashes

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set CanonicalURL (and DownloadURL) on the FileAsset before hashing.
  2. Verify the AssetBuilder inputs (KubernetesVersion, asset mirrors) that produce these URLs.
  3. If calling findHash indirectly, ensure the source URL string parsed successfully (non-nil *url.URL).

Example fix

// before
fileAsset := &FileAsset{} // no URLs
hash, err := findHash(fileAsset)
// after
canonical, err := url.Parse("https://storage.googleapis.com/kubernetes-release/release/v1.28.0/bin/linux/amd64/kubelet")
if err != nil {
	return nil, err
}
fileAsset := &FileAsset{CanonicalURL: canonical, DownloadURL: canonical}
hash, err := findHash(fileAsset)
Defensive patterns

Strategy: validation

Validate before calling

func fileAssetReady(f *assets.FileAsset) error {
	if f.DownloadURL == nil && f.CanonicalURL == nil {
		return fmt.Errorf("FileAsset has no DownloadURL or CanonicalURL")
	}
	return nil
}

Type guard

func hasURL(f *assets.FileAsset) bool { return f != nil && (f.DownloadURL != nil || f.CanonicalURL != nil) }

Try / catch

if err := fileAssetReady(fileAsset); err != nil { return err }
hash, err := findHash(fileAsset)
if err != nil {
	if strings.Contains(err.Error(), "file url is not defined") {
		return fmt.Errorf("file %s: URL fields missing on FileAsset", fileAsset.CanonicalURL)
	}
	return err
}

Prevention

When it happens

Trigger: RemapFile/FindFileAsset flow constructing a FileAsset with nil DownloadURL and nil CanonicalURL, then calling findHash.

Common situations: Misconfigured asset builder where base download URLs were never populated; custom code paths building FileAsset structs manually without setting URLs.

Related errors


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