{"record":{"id":"adbad1bf250a8bb7","repo":"microsoft/aspire","slug":"apphost-resourceservice-apikey-is-not-specified-in","errorCode":null,"errorMessage":"AppHost:ResourceService:ApiKey is not specified in configuration.","messagePattern":"AppHost:ResourceService:ApiKey is not specified in configuration\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Aspire.Hosting/Dashboard/ResourceServiceOptions.cs","lineNumber":38,"sourceCode":"{\n    private string? _apiKey;\n    private byte[]? _apiKeyBytes;\n\n    public ResourceServiceAuthMode? AuthMode { get; set; }\n\n    public string? ApiKey\n    {\n        get => _apiKey;\n        set\n        {\n            _apiKey = value;\n            _apiKeyBytes = value is null ? null : Encoding.UTF8.GetBytes(value);\n        }\n    }\n\n    internal byte[] GetApiKeyBytes()\n    {\n        return _apiKeyBytes ?? throw new InvalidOperationException($\"AppHost:ResourceService:ApiKey is not specified in configuration.\");\n    }\n}\n\ninternal sealed class ValidateResourceServiceOptions : IValidateOptions<ResourceServiceOptions>\n{\n    public ValidateOptionsResult Validate(string? name, ResourceServiceOptions options)\n    {\n        List<string>? errorMessages = null;\n\n        if (options.AuthMode is ResourceServiceAuthMode.ApiKey)\n        {\n            if (string.IsNullOrWhiteSpace(options.ApiKey))\n            {\n                AddError($\"AppHost:ResourceService:ApiKey is required when AppHost:ResourceService:AuthMode is '{nameof(ResourceServiceAuthMode.ApiKey)}'.\");\n            }\n        }\n\n        return errorMessages is { Count: > 0 }","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Dashboard/ResourceServiceOptions.cs#L20-L56","documentation":"ResourceServiceOptions holds an optional API key used to authenticate dashboard/resource-service communication, cached as UTF-8 bytes. GetApiKeyBytes is the forceful accessor: if no key was configured it throws rather than returning null, because the caller requires a key to operate. Options validation normally catches this at startup, but this path can still be hit when the value is missing.","triggerScenarios":"Accessing ResourceServiceOptions.GetApiKeyBytes when configuration lacks the 'AppHost:ResourceService:ApiKey' key — e.g. the dashboard resource service is enabled without an API key set in configuration/environment.","commonSituations":"Running the AppHost/dashboard locally without the expected configuration section; missing ASPNETCORE/environment config source; appsettings for the ResourceService not being loaded; upgrading Aspire where the key became required for the enabled scenario.","solutions":["Set 'AppHost:ResourceService:ApiKey' in configuration (appsettings.json, environment variable AppHost__ResourceService__ApiKey, or user secrets)","Ensure ResourceServiceOptions validation runs at startup so the failure surfaces early with a clear message","Verify the configuration source is actually loaded (correct environment name, config file copied to output)","Only call GetApiKeyBytes when the ApiKey property is confirmed non-null"],"exampleFix":"// before\nvar key = options.GetApiKeyBytes(); // throws when unset\n// after\nvar key = options.ApiKey is null\n    ? throw new InvalidOperationException(\"Configure AppHost:ResourceService:ApiKey before starting the resource service.\")\n    : options.GetApiKeyBytes();","handlingStrategy":"validation","validationCode":"var apiKey = configuration[\"AppHost:ResourceService:ApiKey\"];\nif (string.IsNullOrEmpty(apiKey))\n{\n    throw new InvalidOperationException(\"Set AppHost:ResourceService:ApiKey before using the resource service.\");\n}","typeGuard":"bool HasApiKey(ResourceServiceOptions o) => o.ApiKey is not null;","tryCatchPattern":"try\n{\n    var keyBytes = options.GetApiKeyBytes();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"AppHost:ResourceService:ApiKey\"))\n{\n    // Fail fast with setup guidance pointing at the missing config key.\n}","preventionTips":["Always configure AppHost:ResourceService:ApiKey when the resource service is enabled","Rely on ValidateResourceServiceOptions (IValidateOptions) to catch this at startup","Use environment variable AppHost__ResourceService__ApiKey in containers/CI","Store the key in user secrets locally, never in source control"],"tags":["configuration","api-key","dashboard"],"backgroundTag":"missing-api-key","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}