{"record":{"id":"1864057895f4db95","repo":"microsoft/aspire","slug":"error-parsing-uris-from-configuration-value-key","errorCode":null,"errorMessage":"Error parsing URIs from configuration value '{key}'.","messagePattern":"Error parsing URIs from configuration value '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Shared/IConfigurationExtensions.cs","lineNumber":135,"sourceCode":"    [return: NotNullIfNotNull(nameof(defaultValue))]\n    public static Uri? GetUri(this IConfiguration configuration, string key, Uri? defaultValue = null)\n    {\n        try\n        {\n            var uri = configuration[key];\n\n            if (string.IsNullOrWhiteSpace(uri))\n            {\n                return defaultValue;\n            }\n            else\n            {\n                return new Uri(uri, UriKind.Absolute);\n            }\n        }\n        catch (Exception ex)\n        {\n            throw new InvalidOperationException($\"Error parsing URIs from configuration value '{key}'.\", ex);\n        }\n    }\n\n    /// <summary>\n    /// Parses a configuration value's semicolon-delimited value into an array of <see cref=\"Uri\"/> objects.\n    /// </summary>\n    /// <param name=\"configuration\">The <see cref=\"IConfiguration\"/> this method extends.</param>\n    /// <param name=\"key\">The configuration key.</param>\n    /// <param name=\"defaultValue\">A default value, for when the configuration value is unspecified or white space. May be <see langword=\"null\"/>.</param>\n    /// <returns>The parsed values, or the default value if specified and parsing failed. Returns <see langword=\"null\"/> if <paramref name=\"defaultValue\"/> is <see langword=\"null\"/> and parsing failed.</returns>\n    /// <exception cref=\"InvalidOperationException\">The configuration value could not be accessed, or contained incorrectly formatted data.</exception>\n    [return: NotNullIfNotNull(nameof(defaultValue))]\n    public static Uri[]? GetUris(this IConfiguration configuration, string key, Uri? defaultValue = null)\n    {\n        try\n        {\n            var uris = configuration[key];\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Shared/IConfigurationExtensions.cs#L117-L153","documentation":"IConfigurationExtensions.GetUri reads a configuration value and parses it as an absolute Uri; any failure (null value, relative URI, malformed string, or unexpected exception during parsing) is rethrown as an InvalidOperationException with the config key in the message and the original exception as InnerException.","triggerScenarios":"Calling GetUri(configuration, key) where the key is missing, has an empty value, or contains a string that is not an absolute, well-formed URI (e.g. 'localhost:8080' without scheme, 'http:/broken', relative paths).","commonSituations":"Missing environment variable or appsettings entry for an endpoint URL; URL stored without the 'http(s)://' scheme; typo in the config key; value containing whitespace or quotes copied from a document.","solutions":["Set the config value (env var/appsettings) to a valid absolute URI including the scheme, e.g. 'https://host:port'","Check the exact key name matches between configuration source and GetUri call","Inspect InnerException to see whether the value was null or malformed","If the value is optional, use the Try/nullable variant or check configuration key existence before calling","Trim the value of stray whitespace/quotes in the configuration source"],"exampleFix":"// before\n// ASPIRE_ENDPOINT=http://myhost:18888  (was: myhost:18888)\nvar endpoint = configuration.GetUri(\"ASPIRE_ENDPOINT\");\n// after — with corrected config value the call succeeds\nvar endpoint = configuration.GetUri(\"ASPIRE_ENDPOINT\"); // https://myhost:18888\n// or defensively:\nvar raw = configuration[\"ASPIRE_ENDPOINT\"];\nvar endpoint = Uri.TryCreate(raw, UriKind.Absolute, out var uri) ? uri : new Uri(\"https://localhost:18888\");","handlingStrategy":"validation","validationCode":"var raw = configuration[key];\nif (!Uri.TryCreate(raw, UriKind.Absolute, out _))\n    throw new InvalidOperationException($\"Config '{key}' must be an absolute URI, got: '{raw}'.\");","typeGuard":"static bool IsValidAbsoluteUri(string? s) => Uri.TryCreate(s, UriKind.Absolute, out var u) && (u.Scheme == Uri.UriSchemeHttp || u.Scheme == Uri.UriSchemeHttps);","tryCatchPattern":"try { return configuration.GetUri(key); }\ncatch (InvalidOperationException ex) { logger.LogError(ex, \"Invalid URI in config '{Key}' (inner: {Inner})\", key, ex.InnerException?.Message); throw; }","preventionTips":["Always store URLs with explicit http(s):// scheme in config","Trim whitespace when writing config values","Validate required URI config keys at startup with fail-fast checks"],"tags":["configuration","uri","parsing","invalid-config"],"backgroundTag":"invalid-url-format","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}