docker/compose · error

failed to pull OCI resource %q: %w

Error message

failed to pull OCI resource %q: %w

What it means

After the reference is parsed, the loader contacts the registry through oci.Get(resolver, ref) to fetch the image descriptor. Any failure at the network, authentication, or manifest-resolution level is wrapped into this message, including the offending reference for context. The underlying %w error carries the registry-specific detail (401, 404, DNS, TLS, timeout).

Source

Thrown at pkg/remote/oci.go:141

		return "", fmt.Errorf("OCI remote resource is disabled by %q", OCI_REMOTE_ENABLED)
	}

	if g.offline {
		return "", nil
	}

	local, ok := g.known[path]
	if !ok {
		ref, err := reference.ParseDockerRef(path[len(OciPrefix):])
		if err != nil {
			return "", err
		}

		resolver := oci.NewResolver(g.dockerCli.ConfigFile(), g.httpTransport(ctx), g.insecureRegistries...)

		descriptor, content, err := oci.Get(ctx, resolver, ref)
		if err != nil {
			return "", fmt.Errorf("failed to pull OCI resource %q: %w", ref, err)
		}

		cache, err := cacheDir()
		if err != nil {
			return "", fmt.Errorf("initializing remote resource cache: %w", err)
		}

		local = filepath.Join(cache, descriptor.Digest.Hex())
		if _, err = os.Stat(local); os.IsNotExist(err) {

			// a Compose application bundle is published as an image index
			if images.IsIndexType(descriptor.MediaType) {
				var index spec.Index
				err = json.Unmarshal(content, &index)
				if err != nil {
					return "", err
				}
				found := false

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Read the wrapped error: a 401/403 means auth — run `docker login <registry>` with an account that has pull access, then retry.
  2. A 404 / manifest-unknown means the ref is wrong — verify repository name and tag with `docker manifest inspect <ref>` or in the registry UI.
  3. For network/TLS issues check connectivity (`curl -v https://<registry>/v2/`), proxies, and if the registry is self-signed configure it as insecure so the resolver skips verification.
  4. Retry once if the failure is a transient timeout or DNS blip.

Example fix

# before
docker compose -f oci://registry.example.com/mybundle:latest up
# after (authenticate and verify the ref exists)
docker login registry.example.com
docker manifest inspect registry.example.com/mybundle:latest
docker compose -f oci://registry.example.com/mybundle:latest up
Defensive patterns

Strategy: retry

Validate before calling

// verify ref parses and registry is reachable before Load
if _, err := reference.ParseDockerRef(strings.TrimPrefix(path, "oci://")); err != nil {
    return err // bad reference, fail before any network call
}
resp, err := http.Head(fmt.Sprintf("https://%s/v2/", reference.Domain(ref)))
if err != nil || resp.StatusCode >= 500 { /* expect transient failures, plan a retry */ }

Try / catch

content, err := loader.Load(ctx, path)
if err != nil {
    if strings.Contains(err.Error(), "failed to pull OCI resource") {
        var inner = errors.Unwrap(err)
        if isTransient(inner) { // timeout, 5xx, EOF
            // exponential backoff retry, e.g. 3 attempts
        }
        if isAuthError(inner) { // 401/403: prompt login, do not retry
            return fmt.Errorf("run docker login %s: %w", reference.Domain(ref), err)
        }
    }
    return err
}

Prevention

When it happens

Trigger: Load() on an oci:// path where reference.ParseDockerRef succeeded but oci.Get failed: unknown repository/tag (manifest unknown), missing/not-logged-in registry credentials from g.dockerCli.ConfigFile(), unreachable registry, TLS failure for a registry not listed in g.insecureRegistries, or cancelled context.

Common situations: Forgetting `docker login registry.example.com` before referencing a private bundle; typo in the tag; corporate proxy blocking the registry; self-signed registry used without adding it to insecure registries; expired token or expired pull credentials.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/0ffa72e48d5439a6. Report an issue: GitHub.