kubernetes/kops · error

assetsLocation.fileRepository must be set to remap asset %v

Error message

assetsLocation.fileRepository must be set to remap asset %v

What it means

AssetBuilder.remapURL rewrites canonical kops asset URLs to point at a user-configured file repository (a mirror of kops assets). Before remapping, it reads assetsLocation.fileRepository; if it is empty or assetsLocation is nil, it cannot construct the mirrored URL, so it fails with this error. It guards against silently emitting a half-remapped or unchanged asset URL.

Source

Thrown at pkg/assets/builder.go:453

			if ext == ".sha256" {
				klog.V(2).Infof("Unable to read new sha256 hash file (is this an older/unsupported kubernetes release?)")
			}
		}
	}

	if a.assetsLocation != nil && a.assetsLocation.FileRepository != nil {
		return nil, fmt.Errorf("you might have not staged your files correctly, please execute 'kops get assets --copy'")
	}
	return nil, fmt.Errorf("cannot determine hash for %q (have you specified a valid file location?)", u)
}

func (a *AssetBuilder) remapURL(canonicalURL *url.URL) (*url.URL, error) {
	f := ""
	if a.assetsLocation != nil {
		f = values.StringValue(a.assetsLocation.FileRepository)
	}
	if f == "" {
		return nil, fmt.Errorf("assetsLocation.fileRepository must be set to remap asset %v", canonicalURL)
	}

	fileRepo, err := url.Parse(f)
	if err != nil {
		return nil, fmt.Errorf("unable to parse assetsLocation.fileRepository %q: %v", f, err)
	}

	fileRepo.Path = path.Join(fileRepo.Path, canonicalURL.Path)
	// Escape commas, which are legal in a path but separate locations in CompactString.
	fileRepo.RawPath = strings.ReplaceAll(fileRepo.EscapedPath(), ",", "%2C")

	return fileRepo, nil
}

func NormalizeImage(a *AssetBuilder, image string) string {
	if a.assetsLocation != nil && a.assetsLocation.ContainerProxy != nil {
		containerProxy := strings.TrimSuffix(*a.assetsLocation.ContainerProxy, "/")
		normalized := image

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set cluster.spec.assetsLocation.fileRepository to a valid base URL (e.g. https://artifacts.example.com/kops) and update the cluster (kops update cluster).
  2. If you only wanted container image mirroring, ensure fileRepository is still set or remove assetsLocation entirely so assets use default URLs.
  3. Verify with kops get cluster --yaml that assetsLocation.fileRepository is non-empty before running kops update/replace.

Example fix

// before (cluster spec)
assetsLocation:
  containerRegistry: registry.example.com/kops
// after
assetsLocation:
  containerRegistry: registry.example.com/kops
  fileRepository: https://artifacts.example.com/kops
Defensive patterns

Strategy: validation

Validate before calling

if a.AssetsLocation == nil || values.StringValue(a.AssetsLocation.FileRepository) == "" {
    return fmt.Errorf("assetsLocation.fileRepository must be set before RemapFile")
}

Type guard

func hasFileRepository(al *kops.AssetsLocation) bool {
    return al != nil && al.FileRepository != nil && *al.FileRepository != ""
}

Try / catch

u, err := builder.RemapFile(canonicalURL)
if err != nil {
    var cfgErr *ConfigFieldError
    if errors.As(err, &cfgErr) && strings.Contains(err.Error(), "fileRepository must be set") {
        // prompt for/repair assetsLocation.fileRepository
    }
    return err
}

Prevention

When it happens

Trigger: Calling AssetBuilder.RemapFile (via Build) while AssetsLocation is nil, or AssetsLocation is set with an empty/unset FileRepository field (e.g. Cluster.Spec.AssetsLocation with only containerRegistry set).

Common situations: Users set cluster.spec.assetsLocation.containerRegistry to mirror container images but forget fileRepository, which is separately required to mirror the nodeup/protokube/cni binary assets; or assetsLocation is partially populated by an older cluster spec.

Related errors


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