vxcontrol/pentagi · error

failed to create volume: %w

Error message

failed to create volume: %w

What it means

When the client was constructed without a host directory (hostDir == ""), RunContainer creates a named Docker volume named <containerName>-data to back the /work mount instead of a bind mount. If VolumeCreate fails the container is marked Failed and the error "failed to create volume: %w" is returned. This wraps a daemon error — inspect the cause (named volume name conflicts, driver errors, storage limits).

Source

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

		hostConfig = &container.HostConfig{}
	}

	// prevent containers from auto-starting after OS or docker daemon restart
	// because on startup they create docker.sock directory for DinD if it's enabled
	hostConfig.RestartPolicy = container.RestartPolicy{
		Name:              container.RestartPolicyOnFailure,
		MaximumRetryCount: 5,
	}

	if hostDir == "" {
		volumeName, err := dc.client.VolumeCreate(ctx, client.VolumeCreateOptions{
			Name:   fmt.Sprintf("%s%s", containerName, WorkerVolumeNameSuffix),
			Driver: "local",
			Labels: dc.labels,
		})
		if err != nil {
			defer updateContainerInfo(database.ContainerStatusFailed, "")
			return database.Container{}, fmt.Errorf("failed to create volume: %w", err)
		}
		hostDir = volumeName.Volume.Name
	}
	hostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf("%s:%s", hostDir, WorkFolderPathInContainer))

	if dc.inside {
		// The socket is empty when DOCKER_INSIDE_HOST designates a daemon endpoint
		// instead; binding "" would produce a malformed mount spec.
		if dc.socket != "" {
			hostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf("%s:%s", dc.socket, defaultDockerSocketPath))
		}

		// Point the sandbox's Docker CLI at the designated daemon.
		config.Env = append(config.Env, dc.insideEnv...)

		// TLS material is mounted read-only at the same path on both sides so the
		// injected DOCKER_CERT_PATH resolves unchanged inside the container.
		if dc.insideCertPath != "" {

View on GitHub (pinned to ea665308ba)

Solutions

  1. Inspect the wrapped cause; check for an existing conflicting volume: docker volume ls / docker volume inspect <name>-data, remove it if stale (docker volume rm).
  2. Free disk space on the Docker storage host (docker system df, docker volume prune).
  3. Ensure container names are unique per flow/run so the <name>-data volume name does not collide with a live volume.
  4. If labels/tenants changed, delete the old volume created with the previous labels before rerunning.
  5. Check daemon logs (journalctl -u docker) for volume driver errors.

Example fix

# before: retry loop reuses same container name → same volume name
name := fmt.Sprintf("tool-%s", toolName)             # collides with existing volume tool-x-data
# after
name := fmt.Sprintf("tool-%s-flow-%d", toolName, flowID)  # unique volume per flow
Defensive patterns

Strategy: try-catch

Validate before calling

volName := containerName + "-data"
vols, err := cli.VolumeList(ctx, client.VolumeListOptions{})
if err == nil {
    for _, v := range vols.Volumes {
        if v.Name == volName {
            // exists: decide to reuse or remove before VolumeCreate
            _ = cli.VolumeRemove(ctx, volName, false)
        }
    }
}

Try / catch

_, err := dc.RunContainer(ctx, name, ctype, flowID, cfg, hostCfg)
var derr *client.VolumeCreateError // or match on message
if err != nil && strings.Contains(err.Error(), "failed to create volume") {
    _ = cli.VolumeRemove(context.Background(), name+"-data", true)
    return retryOnce() // recreate volume with fresh state
}

Prevention

When it happens

Trigger: dc.client.VolumeCreate fails: a volume with the same name already exists but is in use with incompatible labels, the 'local' volume driver errors (bad volume options, storage backend full), daemon read-only in an insecure sandbox, or the volume name contains characters rejected by the daemon.

Common situations: Container names reused across runs (e.g. retried flow producing the same <name>-data volume) combined with label/tenant changes; disk full on the Docker volume host; running with a restricted daemon (Docker rootless quota exceeded); name containing invalid characters from an injected tool name.

Related errors


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