helm/helm · error
unable to retrieve manifest: %w
Error message
unable to retrieve manifest: %w
What it means
Client.PullPlugin fetches the artifact, then reads the manifest blob to validate its artifact type; if GetDescriptorData for the manifest descriptor fails it wraps the cause as "unable to retrieve manifest". The manifest bytes were unreadable — missing blob, corrupt transfer, or fetch error.
Source
Thrown at pkg/registry/plugin.go:83
ocispec.MediaTypeImageManifest,
"application/vnd.oci.image.layer.v1.tar",
"application/vnd.oci.image.layer.v1.tar+gzip",
},
})
if err != nil {
return nil, err
}
// Process the result with plugin-specific logic
return c.processPluginPull(genericResult, operation.pluginName)
}
// processPluginPull handles plugin-specific processing of a generic pull result using artifact type
func (c *Client) processPluginPull(genericResult *GenericPullResult, pluginName string) (*PluginPullResult, error) {
// First validate that this is actually a plugin artifact
manifestData, err := c.Generic().GetDescriptorData(genericResult.MemoryStore, genericResult.Manifest)
if err != nil {
return nil, fmt.Errorf("unable to retrieve manifest: %w", err)
}
// Parse the manifest to check artifact type
var manifest ocispec.Manifest
if err := json.Unmarshal(manifestData, &manifest); err != nil {
return nil, fmt.Errorf("unable to parse manifest: %w", err)
}
// Validate artifact type (for OCI v1.1+ manifests)
if manifest.ArtifactType != "" && manifest.ArtifactType != PluginArtifactType {
return nil, fmt.Errorf("expected artifact type %s, got %s", PluginArtifactType, manifest.ArtifactType)
}
// For backwards compatibility, also check config media type if no artifact type
if manifest.ArtifactType == "" && manifest.Config.MediaType != PluginArtifactType {
return nil, fmt.Errorf("expected config media type %s for legacy compatibility, got %s", PluginArtifactType, manifest.Config.MediaType)
}
View on GitHub (pinned to 2a29f1770b)
Solutions
- Retry the pull once
- Inspect the reference with `crane manifest <ref>` to see whether the manifest blob resolves
- Re-push the plugin artifact if the blob is genuinely missing from the registry
Defensive patterns
Strategy: retry
Try / catch
var res *registry.PluginPullResult
err := retry(3, time.Second, func() error {
var e error
res, e = client.PullPlugin(ref, name)
if e != nil && strings.Contains(e.Error(), "unable to retrieve manifest") {
return e // retryable
}
return e
}) Prevention
- Retry plugin pulls once or twice before investigating the registry
- Verify plugin artifacts with `crane manifest` right after publishing so dangling refs are caught early
When it happens
Trigger: registry.Client.PullPlugin / `helm plugin pull` where the manifest blob cannot be read after the generic pull: registry GC removed it, an interrupted upload left a dangling reference, or a network failure mid-pull.
Common situations: Registry garbage collection between push and pull; plugins partially uploaded by CI; unreliable mirrors.
Related errors
- unable to retrieve blob with digest %s: %w
- unable to parse manifest: %w
- manifest does not contain minimum number of descriptors (%d)
- could not load config with mediatype %s
- expected artifact type %s, got %s
AI-assisted analysis of helm/helm@2a29f1770b (2026-08-15).
Data as JSON: /api/errors/ac00fff53e18865f.
Report an issue: GitHub.