docker/compose · error
interactive exec is not supported in dry-run mode
Error message
interactive exec is not supported in dry-run mode
What it means
The dry-run client intentionally blocks ExecAttach because an interactive exec session would perform real I/O with the container and cannot be meaningfully simulated. Static exec calls (create/inspect/resize) pass through, but attaching to the session stream is rejected with 'interactive exec is not supported in dry-run mode'.
Source
Thrown at pkg/dryrun/dryrunclient.go:339
func (d *DryRunClient) ConfigRemove(ctx context.Context, id string, options client.ConfigRemoveOptions) (client.ConfigRemoveResult, error) {
return d.apiClient.ConfigRemove(ctx, id, options)
}
func (d *DryRunClient) ConfigUpdate(ctx context.Context, id string, options client.ConfigUpdateOptions) (client.ConfigUpdateResult, error) {
return d.apiClient.ConfigUpdate(ctx, id, options)
}
func (d *DryRunClient) ContainerCommit(ctx context.Context, container string, options client.ContainerCommitOptions) (client.ContainerCommitResult, error) {
return d.apiClient.ContainerCommit(ctx, container, options)
}
func (d *DryRunClient) ContainerDiff(ctx context.Context, container string, options client.ContainerDiffOptions) (client.ContainerDiffResult, error) {
return d.apiClient.ContainerDiff(ctx, container, options)
}
func (d *DryRunClient) ExecAttach(ctx context.Context, execID string, config client.ExecAttachOptions) (client.ExecAttachResult, error) {
return client.ExecAttachResult{}, errors.New("interactive exec is not supported in dry-run mode")
}
func (d *DryRunClient) ExecInspect(ctx context.Context, execID string, options client.ExecInspectOptions) (client.ExecInspectResult, error) {
return d.apiClient.ExecInspect(ctx, execID, options)
}
func (d *DryRunClient) ExecResize(ctx context.Context, execID string, options client.ExecResizeOptions) (client.ExecResizeResult, error) {
return d.apiClient.ExecResize(ctx, execID, options)
}
func (d *DryRunClient) ContainerExport(ctx context.Context, container string, options client.ContainerExportOptions) (client.ContainerExportResult, error) {
return d.apiClient.ContainerExport(ctx, container, options)
}
func (d *DryRunClient) ContainerLogs(ctx context.Context, container string, options client.ContainerLogsOptions) (client.ContainerLogsResult, error) {
return d.apiClient.ContainerLogs(ctx, container, options)
}
View on GitHub (pinned to ddc4b044b6)
Solutions
- Run exec commands without --dry-run (they are usually safe to test directly)
- Model the check with `docker compose exec -T` outside the dry-run pipeline, keeping only up/create steps in the dry-run pass
- Use `docker compose run --rm --dry-run svc cmd` to approximate what the exec would launch
Example fix
# before docker compose --dry-run exec web cat /etc/hostname # after docker compose exec web cat /etc/hostname
Defensive patterns
Strategy: validation
Validate before calling
# in scripts, route exec away from dry-run mode if [ "$DRY_RUN" = "1" ]; then echo 'skipping exec (unsupported in dry-run)'; else docker compose exec "$@"; fi
Prevention
- Treat --dry-run as covering lifecycle commands only (up/build/create), not exec
- Document which subcommands your scripts dry-run so interactive ones are excluded
When it happens
Trigger: `docker compose exec --dry-run <svc> <cmd>` — or any API path reaching ExecAttach — while dry-run mode is enabled.
Common situations: Dry-running a script that mixes `compose exec` steps to verify command sequencing; forgetting that --dry-run applies to the whole invocation including exec subcommands.
Related errors
- interactive run is not supported in dry-run mode
- canceled
- process still running
- operation cancelled by user
- deleting paths in %s: %w
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/fbb9503b3e0102ed.
Report an issue: GitHub.