vxcontrol/pentagi · critical

failed to pull default image '%s': %w

Error message

failed to pull default image '%s': %w

What it means

If even the default image (dc.defImage, default debian:latest) cannot be pulled, RunContainer returns "failed to pull default image '%s': %w" and marks the container Failed in the database. At this point the environment has no way to obtain any usable sandbox image, so container startup fails hard — the daemon/registry is the culprit, not the caller's image choice.

Source

Thrown at backend/pkg/docker/client.go:283

			logger.WithError(err).Error("failed to update container info in database")
		}
	}

	fallbackDockerImage := func() error {
		logger = logger.WithField("image", dc.defImage)
		logger.Warn("try to use default image")
		config.Image = dc.defImage

		dbContainer, err = dc.db.UpdateContainerImage(ctx, database.UpdateContainerImageParams{
			Image: config.Image,
			ID:    dbContainer.ID,
		})
		if err != nil {
			return fmt.Errorf("failed to update container image in database: %w", err)
		}

		if err := dc.pullImage(ctx, config.Image); err != nil {
			return fmt.Errorf("failed to pull default image '%s': %w", config.Image, err)
		}

		return nil
	}

	if err := dc.pullImage(ctx, config.Image); err != nil {
		logger.WithError(err).Warnf("failed to pull image '%s' and using default image", config.Image)
		if err := fallbackDockerImage(); err != nil {
			defer updateContainerInfo(database.ContainerStatusFailed, "")
			return database.Container{}, err
		}
	}

	logger.Info("creating container")

	config.Hostname = fmt.Sprintf("%08x", crc32.ChecksumIEEE([]byte(containerName)))
	config.WorkingDir = WorkFolderPathInContainer

View on GitHub (pinned to ea665308ba)

Solutions

  1. Pre-pull the default image on the host: docker pull <default-image> (resolves both connectivity and rate limits until restart).
  2. Set DOCKER_DEFAULT_IMAGE to an image available in your environment (local registry/mirror).
  3. Configure registry mirrors or docker login for the private registry; check rate-limit errors in the wrapped cause.
  4. Fix daemon-level network/proxy: HTTP_PROXY/HTTPS_PROXY/NO_PROXY in /etc/systemd/system/docker.service.d/*.conf, then restart docker.
  5. Verify the image tag exists (docker manifest inspect <image>) if DOCKER_DEFAULT_IMAGE was customized.

Example fix

// before (.env)
DOCKER_DEFAULT_IMAGE=debian:bookworm-slim-typo
// after
docker pull debian:bookworm-slim
DOCKER_DEFAULT_IMAGE=debian:bookworm-slim
Defensive patterns

Strategy: retry

Validate before calling

img := cfg.DockerDefaultImage
if img == "" { img = "debian:latest" }
out, err := exec.Command("docker", "manifest", "inspect", img).CombinedOutput()
if err != nil { return fmt.Errorf("default image %s unavailable: %s", img, out) }

Try / catch

err := dc.RunContainer(ctx, name, ctype, flowID, cfg, hostCfg)
if strings.Contains(err.Error(), "failed to pull default image") {
    // transient registry/network failures: retry with backoff
    return retryWithBackoff(ctx, 3, 5*time.Second, func() error {
        return runWithImage(ctx, fallbackImage)
    })
}

Prevention

When it happens

Trigger: dc.pullImage(ctx, dc.defImage) fails: no internet/DNS in the environment, registry rate limiting (Docker Hub 429), private registry requires auth, image name typo in DOCKER_DEFAULT_IMAGE, daemon offline, or insecure-registry TLS rejection.

Common situations: Air-gapped or firewalled deployments that never pre-pulled debian:latest; Docker Hub toomanyrequests rate limit on shared IPs; DOCKER_DEFAULT_IMAGE set to a tag that does not exist; corporate proxy without docker daemon proxy config (HTTP_PROXY in /etc/docker/daemon.json or systemd drop-in).

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/977414060414bfd9. Report an issue: GitHub.