InvalidOperationException: Could not find 'UserSecretsIdAttribute' on assembly

I want to add to this answer, for those in my situation.

I am writing a .NET Core console app, trying to use the secrets manager (not sure it's meant for console apps). The only way I was able to rid myself of the error was using the assembly level attribute on the assembly where I was using the secrets manager.

As I said, I am not sure if the secrets manager is meant for console apps. So maybe there is an issue with .xproj files vs. .csproj files.


There was an update to the user secrets module just recently. Version 1.0.1 and up now requires you specify an assembly-level attribute for the id of the user secrets, or as a fallback, the way it was previously in project.json.

Here is the announcement on GitHub: https://github.com/aspnet/Announcements/issues/209

You can define the secrets id in the .csproj like this:

<PropertyGroup>
  <UserSecretsId>aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed</UserSecretsId>
</PropertyGroup>

This generates the following assembly-level attribute. Alternatively, instead of adding it in the .csproj file, you can of course add it yourself e.g. to Startup.cs:

[assembly: UserSecretsId("aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed")]

Also, you should use:

builder.AddUserSecrets<Startup>();

It will search for that attribute in the assembly of the given type, in this case I used the Startup class.

Note: this will be deprecated in 2.0: (1.0.2 and 1.1.1 have marked it obsolete)

builder.AddUserSecrets();

I checked the source code for the user secrets configuration, and calling AddUserSecrets() without the type does this:

var attribute = entryAssembly.GetCustomAttribute<UserSecretsIdAttribute>();
if (attribute != null)
{
     return AddUserSecrets(configuration, attribute.UserSecretsId);
}

// try fallback to project.json for legacy support
try
{
     var fileProvider = configuration.GetFileProvider();
     return AddSecretsFile(configuration, PathHelper.GetSecretsPath(fileProvider));
}
catch
{ }

// Show the error about missing UserSecretIdAttribute instead an error about missing
// project.json as PJ is going away.
throw MissingAttributeException(entryAssembly);

It's trying to find the UserSecretsId attribute on your assembly, and failing that, checking if it could find it in project.json. Then (as commented) returns an error about the missing attribute as they wouldn't want to complain about project.json anymore as it is being deprecated.