microsoft/aspire · error · InvalidOperationException
Docker Compose file not found at
Error message
Docker Compose file not found at {dockerComposeFilePath} What it means
DockerComposeUpAsync runs 'compose up' during deployment, but first checks that docker-compose.yaml exists in the environment's publish output path. If the file is absent, deployment cannot proceed and it throws InvalidOperationException with the expected full path. This means the publish step that generates the compose file did not run or wrote elsewhere.
Solutions
- Run the full publish/deploy pipeline ( aspire publish then aspire deploy, or the complete pipeline) so docker-compose.yaml is generated before compose up.
- Check the path in the error message and verify the file exists there; if not, inspect earlier publish step logs for failures.
- Verify no custom output-path configuration moved the artifacts to a different directory.
Example fix
// before (deploy without publish output) aspire deploy // after: generate the compose file first aspire publish aspire deploy // and confirm <output-path>/docker-compose.yaml exists
Defensive patterns
Strategy: validation
Validate before calling
// before deploy, verify the compose file exists in the output path
var outputPath = PublishingContextUtils.GetEnvironmentOutputPath(context, environmentResource);
var composeFile = Path.Combine(outputPath, "docker-compose.yaml");
if (!File.Exists(composeFile))
throw new InvalidOperationException($"Run publish first; expected compose file at {composeFile}"); Prevention
- Always run the publish step before deploy so docker-compose.yaml is generated
- Check earlier publish step logs for silent failures before deploying
- Verify custom output-path configuration matches where deploy looks for artifacts
When it happens
Trigger: Deploying a DockerComposeEnvironment when the publish step did not emit docker-compose.yaml into the environment output directory — publish phase skipped, output path customized, or the file named/emitted differently by an earlier failing step.
Common situations: Running the deploy step standalone without publish; CI pipelines that cleaned or relocated the artifacts folder; a publishing failure earlier in the pipeline silently leaving no output; stale output path configuration (PublishingContextUtils.GetEnvironmentOutputPath pointing at the wrong folder).
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Java application ' ' cannot be published because its has no…
- Java application ' ' cannot be published because the…
- Ensure ' ' is installed and available on PATH.
- Resource ' ' is configured to publish as a Docker Compose…
- Volume source and target must be set
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/1c50206b3ce1202e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Docker/DockerComposeEnvironmentResource.cs:436
}
foreach (var (name, value) in activationEnvironmentVariables)
{
environmentVariables.TryAdd(name, value);
}
}
private static OtlpExporterAnnotation? GetEffectiveOtlpExporterAnnotation(IResource resource)
=> resource.Annotations.OfType<OtlpExporterAnnotation>().LastOrDefault();
private async Task DockerComposeUpAsync(PipelineStepContext context)
{
var outputPath = PublishingContextUtils.GetEnvironmentOutputPath(context, this);
var dockerComposeFilePath = Path.Combine(outputPath, "docker-compose.yaml");
if (!File.Exists(dockerComposeFilePath))
{
throw new InvalidOperationException($"Docker Compose file not found at {dockerComposeFilePath}");
}
var runtime = await context.Services.GetRequiredService<IContainerRuntimeResolver>().ResolveAsync(context.CancellationToken).ConfigureAwait(false);
var deployTask = await context.ReportingStep.CreateTaskAsync(
new MarkdownString($"Running compose up for **{Name}** using **{runtime.Name}**"),
context.CancellationToken).ConfigureAwait(false);
await using (deployTask.ConfigureAwait(false))
{
try
{
var composeContext = CreateComposeOperationContext(context);
await runtime.ComposeUpAsync(composeContext, context.CancellationToken).ConfigureAwait(false);
// Persist deployment state so destroy can find the compose file and project name
var deploymentStateManager = context.Services.GetRequiredService<IDeploymentStateManager>();
var stateSection = await deploymentStateManager.AcquireSectionAsync($"DockerCompose:{Name}", context.CancellationToken).ConfigureAwait(false);View on GitHub (pinned to 25830f84bd)