kubernetes/kops · error
failed to build manifest path. Path was empty
Error message
failed to build manifest path. Path was empty
What it means
buildManifestDirectory creates the directory kubelet watches for static pods (spec.kubelet.podManifestPath). Since a static-pod manifest directory is mandatory for the kubelet setup nodeup performs, an empty PodManifestPath is treated as a hard configuration error rather than silently skipped.
Source
Thrown at nodeup/pkg/model/kubelet.go:458
// kubeletPath returns the path of the kubelet based on distro
func (b *KubeletBuilder) kubeletPath() string {
return b.binaryPath() + "/kubelet"
}
// getECRCredentialProviderPath returns the path of the ECR Credentials Provider based on distro and archiecture
func (b *KubeletBuilder) getECRCredentialProviderPath() string {
return b.binaryPath() + "/ecr-credential-provider"
}
// getGCPCredentialProviderPath returns the path of the GCP Credentials Provider based on distro and archiecture
func (b *KubeletBuilder) getGCPCredentialProviderPath() string {
return b.binaryPath() + "/gcp-credential-provider"
}
// buildManifestDirectory creates the directory where kubelet expects static manifests to reside
func (b *KubeletBuilder) buildManifestDirectory(kubeletConfig *kops.KubeletConfigSpec) (*nodetasks.File, error) {
if kubeletConfig.PodManifestPath == "" {
return nil, fmt.Errorf("failed to build manifest path. Path was empty")
}
directory := &nodetasks.File{
Path: kubeletConfig.PodManifestPath,
Type: nodetasks.FileType_Directory,
Mode: s("0755"),
}
return directory, nil
}
// buildSystemdEnvironmentFile renders the environment file for the kubelet
func (b *KubeletBuilder) buildSystemdEnvironmentFile(ctx context.Context, kubeletConfig *kops.KubeletConfigSpec) (*nodetasks.File, error) {
// TODO: Dump the separate file for flags - just complexity!
flags, err := flagbuilder.BuildFlags(kubeletConfig)
if err != nil {
return nil, fmt.Errorf("error building kubelet flags: %v", err)
}
if b.UsesSecondaryIP() {View on GitHub (pinned to 4c8573c808)
Solutions
- Set spec.kubelet.podManifestPath to a valid directory, e.g. /etc/kubernetes/manifests
- Do not set it to an empty string; omit the field entirely if defaults apply
- kops edit cluster, fix the value, then kops update cluster
- Check kops version-specific defaults if upgrading changed behavior
Example fix
// before kubelet: podManifestPath: "" // after kubelet: podManifestPath: /etc/kubernetes/manifests
Defensive patterns
Strategy: validation
Validate before calling
if cluster.Spec.Kubelet != nil && cluster.Spec.Kubelet.PodManifestPath == "" {
return errors.New("kubelet.podManifestPath must not be empty; use e.g. /etc/kubernetes/manifests")
} Try / catch
dir, err := b.buildManifestDirectory(kubeletConfig)
if err != nil {
return fmt.Errorf("set spec.kubelet.podManifestPath in the cluster spec: %w", err)
} Prevention
- Never set podManifestPath to an empty string; omit the field to use defaults
- Keep /etc/kubernetes/manifests as the standard path unless you have a reason
- Add spec linting in CI to catch cleared required fields
When it happens
Trigger: buildManifestDirectory -> kubeletConfig.PodManifestPath == "", i.e. the cluster spec explicitly sets kubelet.podManifestPath to "" (Go zero value when cleared) while the KubeletBuilder.Build path still requires the directory.
Common situations: Users clearing podManifestPath in the cluster spec believing it disables static pods; config templates omitting the field where downstream code requires it; migrating specs between kops versions with different defaults.
Related errors
- invalid feature gate value %q=%q: %w
- error building kubelet server cert: %v
- error building kubelet config: %v
- error loading AWS config: %v
- error querying Azure instance metadata: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/5785d41053b9cc95.
Report an issue: GitHub.