While working on a local microservices setup using Aspire, I ran into a confusing issue while trying to emulate Azure Event Hubs. The Aspire framework generally streamlines local development with cloud-native components, but this time it stumbled on a critical configuration detail that wasn’t immediately obvious.

The Problem: Emulator Fails Without Storage Path

I wanted to run my EventHub setup locally using Aspire’s emulator support. Everything seemed straightforward. I followed the official documentation closely and wired things up like so:

var builder = DistributedApplication.CreateBuilder(args);

var eventHubs = builder.AddAzureEventHubs("event-hubs")
                       .RunAsEmulator();

eventHubs.AddHub("messages");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(eventHubs);

// After adding all resources, run the app...
In my case, I added a conditional to distinguish between publish and development modes:
var eventHubs = builder.ExecutionContext.IsPublishMode 
    ? builder.AddConnectionString("event-hubs")
    : builder.AddAzureEventHubs("event-hubs")
        .RunAsEmulator();

However, when I ran the application locally, I was greeted by a cryptic exception:

System.AggregateException: ‘One or more errors occurred. (Could not determine an appropriate location for local storage. Set the Aspire:Store:Path setting to a folder where the App Host content should be stored.)’

Removing the EventHub integration made the error go away, but re-adding it brought the issue back. Clearly, the emulator required some kind of local storage setup.

What the Docs Do (and Don’t) Say

The documentation briefly mentions that a local store is created in the ./obj folder of the Application Host. It also notes that you can override this by setting the ASPIRE__STORE__PATH environment variable. The storage path is used to persist data required by the emulator and is namespaced with a .aspire prefix to prevent conflicts or accidental deletions.

But what it doesn’t explain is why this requirement might suddenly break your project, especially if everything looks correct on the surface. The documentation references it a little bit here.

The store is created in the ./obj folder of the Application Host. If the ASPIRE__STORE__PATH environment variable is set this will be used instead.
The store is specific to a IDistributedApplicationBuilder instance such that each application can’t conflict with others. A .aspire prefix is also used to ensure that the folder can be deleted without impacting unrelated files.

The Real Culprit: Version Mismatch

After some head-scratching, I realized I had started my project using the default Aspire 9.0.0 template. At the time, I didn’t think much about it when NuGet pulled in a slightly newer version of the EventHubs emulator package. Minor version bump, right?

Still stuck, I reached out on the Aspire Discord. David Fowler responded quickly (shout-out to him!), and pinpointed the issue: mismatched versions between the core Aspire SDK and the Azure EventHub integration.

The Fix: Align Aspire Versions

The fix was straightforward once I knew what to look for. I just needed to align the versions of the Aspire SDK and the related NuGet packages in my AppHost.csproj:

I updated my AppHost .csproj and it worked perfectly.

Just had to make two changes:

<Sdk Name="Aspire.AppHost.Sdk" Version="9.3.0" />

and

  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.AppHost" Version="9.3.0" />
    <PackageReference Include="Aspire.Hosting.Azure.EventHubs" Version="9.3.0" />
  </ItemGroup>

Once the versions were aligned, everything worked perfectly. The emulator spun up with no storage path errors, and EventHub messages started flowing as expected.

Conclusion

The Aspire ecosystem makes developing cloud-native apps locally more accessible, but it’s not immune to versioning pitfalls. When using emulators like Azure Event Hubs, ensure that all Aspire-related packages and SDK versions are aligned. The storage path error was just a symptom — the root cause was a version mismatch that caused the emulator to misbehave.

Lesson learned: always check your versioning, even when the changes seem minor. It could save you hours of debugging.

Even with minor releases, watch out! Make sure your keep yourself in lockstep across your projects. I think this will be a reality as they continue to iterate quickly.