microsoft / microsoft/aspire

EF migration tool inherits ASPNETCORE_URLS referencing an endpoint it does not produce

Open
#18,805 0 comments 1 reaction 0 assignees View on GitHub
area-integrations entityframework
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

`Aspire.Hosting.EntityFrameworkCore` creates a hidden `dotnet-ef` executable for an ASP.NET
Core project. The executable appears to inherit the startup project's generated
`ASPNETCORE_URLS` value.

That value contains a `portForServing` expression referencing the HTTPS endpoint of the
original project. The hidden EF tool executable does not produce this endpoint, so DCP cannot
substitute the environment variable:

```text
Could not perform substitution for environment variable ASPNETCORE_URLS:
error calling portForServing: service '/web-api-https' referenced by
Executable '/ef-tool-api-migrations-...' specification is not produced
by this Executable
```
The process subsequently fails with:

Unhandled exception: The SSL connection could not be established, see inner exception.

It is unclear whether the SSL exception is related to the invalid inherited environment or is a
separate issue because the inner exception and stack trace are not included in the migration
resource output.

### Aspire configuration

```C#
var database = builder.AddPostgres("postgres")
.AddDatabase("app-database");

var api = builder.AddProject("web-api")
.WithReference(database)
.WaitFor(database);

api.AddEFMigrations(
"api-migrations",
"SampleApp.Persistence.AppDbContext")
.WithMigrationsProject()
.WithReference(database)
.WaitFor(database)
.RunDatabaseUpdateOnStart();
```

The startup project has HTTP and HTTPS launch profiles:
```json
{
"profiles": {
"http": {
"commandName": "Project",
"applicationUrl": "http://localhost:5000"
},
"https": {
"commandName": "Project",
"applicationUrl": "https://localhost:7000;http://localhost:5000"
}
}
}

```

### Expected Behavior

The hidden dotnet-ef executable should not inherit ASPNETCORE_URLS or endpoint expressions
belonging to the ASP.NET Core startup project.

Alternatively, inherited endpoint expressions should be resolved against the original project
resource.

The migration should execute using the referenced database connection string.
### Actual behavior

DCP attempts to resolve the startup project's HTTPS endpoint against the hidden EF executable:

service '/web-api-https' referenced by Executable
'/ef-tool-api-migrations-abcdefgh' specification is not produced
by this Executable

The substitution error is emitted twice. The process then starts but terminates with an SSL
exception.

Complete relevant log

Using startup project: /home/user/source/SampleApp/src/WebApi/WebApi.csproj
Using target project: /home/user/source/SampleApp/src/Persistence/Persistence.csproj
Executing dotnet tool exec dotnet-ef --yes -- database update --no-build --no-color --prefix-
output --verbose --project /home/user/source/SampleApp/src/Persistence/Persistence.csproj
--startup-project /home/user/source/SampleApp/src/WebApi/WebApi.csproj --configuration Debug
--framework net10.0 --context SampleApp.Persistence.AppDbContext
Executing command 'start'.
Successfully executed command 'start'.
[sys] Could not perform substitution for environment variable ASPNETCORE_URLS': Error =
template: envar:1:22: executing "envar" at : error calling
portForServing: service '/web-api-https' referenced by Executable '/ef-tool-api-migrations-
abcdefgh' specification is not produced by this Executable
[sys] Could not perform substitution for environment variable ASPNETCORE_URLS': Error =
template: envar:1:22: executing "envar" at : error calling
portForServing: service '/web-api-https' referenced by Executable '/ef-tool-api-migrations-
abcdefgh' specification is not produced by this Executable
[sys] Starting process...: Cmd = /home/user/.dotnet/dotnet, Args = ["tool", "exec", "dotnet-
ef", "--yes", "--", "database", "update", "--no-build", "--no-color", "--prefix-output",
"--verbose", "--project", "/home/user/source/SampleApp/src/Persistence/Persistence.csproj",
"--startup-project", "/home/user/source/SampleApp/src/WebApi/WebApi.csproj", "--configuration",
"Debug", "--framework", "net10.0", "--context", "SampleApp.Persistence.AppDbContext"]
Unhandled exception: The SSL connection could not be established, see inner exception.

EF Core Update Database command failed: dotnet-ef command failed
Failure executing command 'ef-database-update'. Error message: dotnet-ef command failed
EF Core database update on startup failed for resource 'api-migrations'. dotnet-ef command
failed

### Steps To Reproduce

1. Create an ASP.NET Core project with HTTP and HTTPS endpoints.
2. Add an EF Core DbContext, optionally in a separate migrations project.
3. Add the startup project to an Aspire AppHost.
4. Register migrations using AddEFMigrations.
5. Enable RunDatabaseUpdateOnStart.
6. Start the AppHost or execute the Update Database resource command.
7. Inspect the hidden ef-tool-* resource logs.

### Exceptions (if any)

The complete exception type, inner exception, and stack trace are not included in the resource
output. The only exception message reported is:

Unhandled exception: The SSL connection could not be established, see inner exception.

Immediately before it, DCP reports:

Could not perform substitution for environment variable ASPNETCORE_URLS:
error calling portForServing: service '/web-api-https' referenced by
Executable '/ef-tool-api-migrations-abcdefgh' specification is not produced
by this Executable.

### Aspire doctor output

Aspire Environment Check

========================

Aspire
✅ Aspire CLI version 13.5.0-preview.1.26365.1 (channel: daily)
✅ Developer Control Plane (DCP) connection using an ephemeral DCP-managed certificate
succeeded
⚠️ No trusted developer certificate was available for the Developer Control Plane (DCP)
developer certificate connection check
Run `aspire certs trust` to create and trust a developer certificate.
Details:
No fully trusted exportable developer certificate with a private key was found.

AppHost
✅ AppHost version 13.5.0-preview.1.26365.1 (Aspire/BTR.AppHost/BTR.AppHost.csproj)

.NET SDK
✅ .NET 10.0.300 installed (x64)

Container Runtime
✅ Docker v29.6.1: running (auto-detected (default)) ← active
✅ Podman v5.8.4: running (available)

Environment
✅ Operating system: Linux Fedora 44
⚠️ HTTPS development certificate is only partially trusted
Set SSL_CERT_DIR in your shell profile: export
SSL_CERT_DIR="$SSL_CERT_DIR:/etc/pki/tls/certs:/home/axi/.aspnet/dev-certs/trust"
See: https://aka.ms/aspire-prerequisites#dev-certs
Details:
The certificate is in the trusted store, but SSL_CERT_DIR is not configured to
include '/home/axi/.aspnet/dev-certs/trust'. Some applications may not trust the
certificate. 'aspire run' will configure this automatically.

Development Tools
⚠️ VS Code is installed, but the Aspire extension is not installed
Install the Aspire extension from the VS Code Marketplace for an integrated Aspire
experience.
See: https://aka.ms/aspire/vscode-extension

Summary: 7 passed, 3 warnings, 0 failed
For detailed prerequisites: https://aka.ms/aspire-prerequisites

Aspire CLI Installations
========================

╭───────────────────────────────┬──────────────────────────────┬─────────┬────────┬─────────────╮
│ Path │ Version │ Channel │ Route │ PATH status │
├───────────────────────────────┼──────────────────────────────┼─────────┼────────┼─────────────┤
│ /home/axi/.aspire/bin/aspire │ 13.5.0-preview.1.26365.1+7a1 │ daily │ script │ active │
│ (current) │ fb6080c34db4b9e2865ef5f41e78 │ │ │ │
│ │ 05a63e1c7 │ │ │ │
╰───────────────────────────────┴──────────────────────────────┴─────────┴────────┴─────────────╯

### Anything else?

Running the EF tool directly outside Aspire succeeds:

$ dotnet tool exec dotnet-ef --yes -- --version
Entity Framework Core .NET Command-line Tools
10.0.10

TLS access to NuGet also succeeds:

$ curl -I https://api.nuget.org/v3/index.json
HTTP/2 200

PostgreSQL reaches the healthy state before the migration command executes.

### Attempted workaround

I attempted to remove ASPNETCORE_URLS from the hidden tool resource:

```csharp
api.AddEFMigrations(
"api-migrations",
"SampleApp.Persistence.AppDbContext",
configureToolResource: tool =>
{
tool.WithEnvironment(context =>
context.EnvironmentVariables.Remove("ASPNETCORE_URLS"));
})
.WithMigrationsProject()
.WithReference(database)
.WaitFor(database)
.RunDatabaseUpdateOnStart();
```

The same substitution error still occurs. This may indicate that the endpoint-derived
environment annotation is applied after the user-provided tool configuration or cannot be
removed through this callback.

### Environment

- OS: Fedora 44, Linux x64
- .NET SDK: 10.0.300
- .NET runtime: 10.0.8
- EF Core tools: 10.0.10
- Target framework: net10.0
- Aspire.AppHost.Sdk: 13.5.0-preview.1.26365.1
- Aspire.Hosting.EntityFrameworkCore: 13.5.0-preview.1.26365.1
- Aspire.Hosting.PostgreSQL: 13.5.0-preview.1.26365.1
- Aspire.Npgsql.EntityFrameworkCore.PostgreSQL: 13.5.0-preview.1.26365.1

Contributor guide

Open the contributing guide

Research direction

Start by tracing the AddEFMigrations hidden tool resource and how it receives ASPNETCORE_URLS; the issue does not name source files or tests. Reproduce with the HTTP/HTTPS startup profiles and RunDatabaseUpdateOnStart, then verify that the tool no longer attempts to resolve the startup project's HTTPS endpoint and that the database migration runs.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
databases, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.