docker/compose · error
creating fetcher for %s: %w
Error message
creating fetcher for %s: %w
What it means
GetBlob asks the containerd remotes.Resolver for a Fetcher bound to the repository reference; if that fails (auth, repository does not exist, resolver misconfiguration, unreachable registry) the error is wrapped with the ref. This happens before any blob request is made, so it always indicates a reference/registry-level problem, not a problem with the specific blob.
Source
Thrown at internal/oci/resolver.go:106
fetch, err := fetcher.Fetch(ctx, descriptor)
if err != nil {
return spec.Descriptor{}, nil, err
}
content, err := io.ReadAll(fetch)
if err != nil {
return spec.Descriptor{}, nil, err
}
return descriptor, content, nil
}
// GetBlob retrieves the content of a blob descriptor (e.g. an artifact layer)
// from the repository ref belongs to. Unlike Get it doesn't Resolve the
// digest, as the registry manifests endpoint only serves actual manifests;
// blob content must be fetched directly from the blobs endpoint.
func GetBlob(ctx context.Context, resolver remotes.Resolver, ref reference.Named, descriptor spec.Descriptor) ([]byte, error) {
fetcher, err := resolver.Fetcher(ctx, ref.String())
if err != nil {
return nil, fmt.Errorf("creating fetcher for %s: %w", ref, err)
}
fetch, err := fetcher.Fetch(ctx, descriptor)
if err != nil {
return nil, fmt.Errorf("fetching blob %s: %w", descriptor.Digest, err)
}
defer func() { _ = fetch.Close() }()
// bound the read by the declared size so a rogue registry can't cause
// unbounded allocation; the extra byte detects oversized responses.
content, err := io.ReadAll(io.LimitReader(fetch, descriptor.Size+1))
if err != nil {
return nil, fmt.Errorf("reading blob %s: %w", descriptor.Digest, err)
}
if int64(len(content)) != descriptor.Size {
return nil, fmt.Errorf("blob %s size mismatch: expected %d bytes, got %d", descriptor.Digest, descriptor.Size, len(content))
}
// GetBlob bypasses containerd's content store, so integrity must be
// checked here before callers write the bytes to disk.
if err := descriptor.Digest.Validate(); err != nil {View on GitHub (pinned to ddc4b044b6)
Solutions
- Authenticate against the registry: docker login <registry> (or configure the resolver's auth).
- Verify the ref: the repository must exist and the name be fully qualified (registry/account/repo).
- Check connectivity/TLS: curl -v https://<registry>/v2/ and inspect proxy/CA settings.
- Re-run with debug logging to see the wrapped containerd error, which names the real cause (401, 404, TLS, DNS).
Example fix
# before $ docker compose --project-name demo pull # not logged in to private registry # after $ docker login registry.example.com $ docker compose --project-name demo pull
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: does the repo resolve and are credentials in place?
if _, err := resolver.Resolve(ctx, ref.String()); err != nil {
return fmt.Errorf("cannot access %s (auth/repo): %w", ref, err)
} Try / catch
fetcher, err := resolver.Fetcher(ctx, ref.String())
if err != nil {
if errors.Is(err, errdefs.ErrUnauthorized) || errors.Is(err, errdefs.ErrNotFound) {
// guide the user: login or check repo name
}
return fmt.Errorf("creating fetcher for %s: %w", ref, err)
} Prevention
- docker login before pulling/pushing private artifacts.
- Fully qualify refs (registry/namespace/repo).
- Surface the wrapped containerd error; it distinguishes 401 vs 404 vs TLS.
When it happens
Trigger: resolver.Fetcher(ctx, ref.String()) failing: unauthenticated pull from a private repo, expired registry token/credentials, typo'd repository name in the ref, network/DNS failure reaching the registry, or a resolver built without the right auth handler.
Common situations: docker compose pull/push of an OCI artifact from a private registry without docker login; stale cached credentials; corporate proxies intercepting registry TLS; refs normalized incorrectly (missing namespace/tag).
Related errors
- reading blob %s: %w
- failed to resolve digest for %s: %w
- failed to pull OCI resource %q: %w
- unsupported OCI version: %s
- fetching blob %s: %w
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/7aa8c3d06f87701e.
Report an issue: GitHub.