docker/compose · error

OCI remote resource is disabled by %q

Error message

OCI remote resource is disabled by %q

What it means

The OCI remote loader resolves paths with the oci:// prefix by pulling a Compose bundle from an OCI registry. Before doing anything it checks the experimental flag via ociRemoteLoaderEnabled(); when the feature flag is unset, Load refuses to proceed. The %q in the message names the environment variable (COMPOSE_EXPERIMENTAL_OCI_REMOTE) that controls the switch.

Source

Thrown at pkg/remote/oci.go:123

func (g *ociRemoteLoader) httpTransport(ctx context.Context) http.RoundTripper {
	g.transportOnce.Do(func() {
		g.transport = desktop.ProxyTransportFor(ctx, g.dockerCli.Client())
	})
	return g.transport
}

func (g *ociRemoteLoader) Accept(path string) bool {
	return strings.HasPrefix(path, OciPrefix)
}

//nolint:gocyclo
func (g *ociRemoteLoader) Load(ctx context.Context, path string) (string, error) {
	enabled, err := ociRemoteLoaderEnabled()
	if err != nil {
		return "", err
	}
	if !enabled {
		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)

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Set the experiment flag: export COMPOSE_EXPERIMENTAL_OCI_REMOTE=1 (or true) in your shell or compose env file, then rerun.
  2. Verify the variable actually reaches the compose process (check with `docker compose config --environment` or print env in CI) — a missing or misspelled name keeps the loader disabled.
  3. If you do not intend to use OCI remotes, remove the oci:// path from -f/--file arguments and point at a local compose file instead.

Example fix

# before
docker compose -f oci://registry.example.com/mybundle up
# after
export COMPOSE_EXPERIMENTAL_OCI_REMOTE=1
docker compose -f oci://registry.example.com/mybundle up
Defensive patterns

Strategy: validation

Validate before calling

// before invoking a loader that accepts oci:// paths
if strings.HasPrefix(path, "oci://") {
    if os.Getenv("COMPOSE_EXPERIMENTAL_OCI_REMOTE") != "1" && os.Getenv("COMPOSE_EXPERIMENTAL_OCI_REMOTE") != "true" {
        return fmt.Errorf("set COMPOSE_EXPERIMENTAL_OCI_REMOTE=1 to use OCI remote resources")
    }
}

Prevention

When it happens

Trigger: Calling loader Load() (or running `docker compose -f oci://...` downstream) with a path starting with the oci:// prefix while the COMPOSE_EXPERIMENTAL_OCI_REMOTE environment variable is not set to a truthy value ('1'/'true'). Accept() returned true because of the prefix, but the gate check then fails.

Common situations: Users trying the OCI remote bundle feature on a compose version where it is still gated behind an experiment flag; CI environments that strip env vars; scripts assuming the feature is on by default after seeing docs or blog posts.

Related errors


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