docker/compose · error

no available sync implementation

Error message

no available sync implementation

What it means

Compose watch's file sync currently has exactly one implementation: a tar-batching transfer via the Moby Untar API. The COMPOSE_EXPERIMENTAL_WATCH_TAR env var gates it; when parsed as false, getSyncImplementation has nothing left to return and errors out. This is effectively a kill-switch for sync, not a real selection mechanism.

Source

Thrown at pkg/compose/watch.go:127

	w.stopFn = nil
	err := <-w.errCh
	return err
}

// getSyncImplementation returns an appropriate sync implementation for the
// project.
//
// Currently, an implementation that batches files and transfers them using
// the Moby `Untar` API.
func (s *composeService) getSyncImplementation(project *types.Project) (sync.Syncer, error) {
	var useTar bool
	if useTarEnv, ok := os.LookupEnv("COMPOSE_EXPERIMENTAL_WATCH_TAR"); ok {
		useTar, _ = strconv.ParseBool(useTarEnv)
	} else {
		useTar = true
	}
	if !useTar {
		return nil, errors.New("no available sync implementation")
	}

	return sync.NewTar(project.Name, tarDockerClient{s: s}), nil
}

func (s *composeService) Watch(ctx context.Context, project *types.Project, options api.WatchOptions) error {
	wait, err := s.watch(ctx, project, options)
	if err != nil {
		return err
	}
	return wait()
}

type watchRule struct {
	types.Trigger
	include watch.PathMatcher
	ignore  watch.PathMatcher
	service string

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Unset the variable: `unset COMPOSE_EXPERIMENTAL_WATCH_TAR`
  2. Set it explicitly to 1/true: `COMPOSE_EXPERIMENTAL_WATCH_TAR=1 docker compose watch`
  3. If you only need rebuilds, change watch actions to `rebuild` which do not require the sync implementation

Example fix

# before
COMPOSE_EXPERIMENTAL_WATCH_TAR=0 docker compose watch
# after
docker compose watch  # or COMPOSE_EXPERIMENTAL_WATCH_TAR=1
Defensive patterns

Strategy: validation

Validate before calling

if [ -n "$COMPOSE_EXPERIMENTAL_WATCH_TAR" ] && ! [[ "$COMPOSE_EXPERIMENTAL_WATCH_TAR" =~ ^(1|t|T|true|TRUE)$ ]]; then
  unset COMPOSE_EXPERIMENTAL_WATCH_TAR
fi
docker compose watch

Prevention

When it happens

Trigger: `docker compose watch` (with any service using a sync/sync_exec watch action) while COMPOSE_EXPERIMENTAL_WATCH_TAR is set to a falsey value (0, false, FALSE, no).

Common situations: Users toggling experimental env vars to work around watch issues and disabling the only sync backend; CI environments carrying COMPOSE_EXPERIMENTAL_WATCH_TAR=0 globally; stale advice in scripts from when multiple sync implementations existed.

Related errors


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