{"record":{"id":"7aff7f4d93bd5236","repo":"dotnet/aspnetcore","slug":"the-antiforgery-system-has-the-configuration-value","errorCode":null,"errorMessage":"The antiforgery system has the configuration value {optionName} = {value}, but the current request is not an SSL request.","messagePattern":"The antiforgery system has the configuration value (.+?) = (.+?), but the current request is not an SSL request\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Antiforgery/src/Internal/DefaultAntiforgery.cs","lineNumber":256,"sourceCode":"        {\n            // Persist the new cookie if it is not null.\n            _tokenStore.SaveCookieToken(httpContext, cookieToken);\n        }\n\n        if (!_options.SuppressXFrameOptionsHeader && !httpContext.Response.Headers.ContainsKey(HeaderNames.XFrameOptions))\n        {\n            // Adding X-Frame-Options header to prevent ClickJacking. See\n            // http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-10\n            // for more information.\n            httpContext.Response.Headers.XFrameOptions = \"SAMEORIGIN\";\n        }\n    }\n\n    private void CheckSSLConfig(HttpContext context)\n    {\n        if (_options.Cookie.SecurePolicy == CookieSecurePolicy.Always && !context.Request.IsHttps)\n        {\n            throw new InvalidOperationException(Resources.FormatAntiforgery_RequiresSSL(\n                string.Join(\".\", nameof(AntiforgeryOptions), nameof(AntiforgeryOptions.Cookie), nameof(CookieBuilder.SecurePolicy)),\n                nameof(CookieSecurePolicy.Always)));\n        }\n    }\n\n    private static IAntiforgeryFeature GetAntiforgeryFeature(HttpContext httpContext)\n    {\n        var antiforgeryFeature = httpContext.Features.Get<IAntiforgeryFeature>();\n        if (antiforgeryFeature is null)\n        {\n            antiforgeryFeature = new AntiforgeryFeature();\n            httpContext.Features.Set(antiforgeryFeature);\n        }\n\n        return antiforgeryFeature;\n    }\n\n    private IAntiforgeryFeature GetCookieTokens(HttpContext httpContext)","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Antiforgery/src/Internal/DefaultAntiforgery.cs#L238-L274","documentation":"Thrown by CheckSSLConfig (DefaultAntiforgery.cs:252-259) when AntiforgeryOptions.Cookie.SecurePolicy is set to CookieSecurePolicy.Always but the current request is not HTTPS. This is a fail-fast guard: the secure cookie policy is meaningless over plain HTTP, so the system throws InvalidOperationException rather than silently emitting an insecure cookie. CheckSSLConfig is called at the start of every public antiforgery method (GetAndStoreTokens, GetTokens, IsRequestValidAsync, ValidateRequestAsync, SetCookieTokenAndHeader).","triggerScenarios":"Any call to IAntiforgery while Cookie.SecurePolicy == Always and httpContext.Request.IsHttps == false. This includes local development over http://localhost, or a production deployment behind a reverse proxy that terminates TLS and forwards plain HTTP to the app.","commonSituations":"Local development without HTTPS; reverse proxy (Nginx/HAProxy/Azure App Gateway) terminating TLS and not forwarding the X-Forwarded-Proto header; UseHttpsRedirection missing from the pipeline; a misconfigured forward headers setup.","solutions":["Ensure the app receives HTTPS: call app.UseHttpsRedirection() or use HTTPS in development (dotnet run with launchSettings https profile).","If behind a reverse proxy that terminates TLS, configure UseForwardedHeaders so IsHttps reflects the original scheme via X-Forwarded-Proto.","If HTTPS isn't possible, set Cookie.SecurePolicy to None or SameAsRequest instead of Always — though this reduces security.","For local dev, use the HTTPS URL (https://localhost:5001) rather than http://localhost:5000."],"exampleFix":"// before — SecurePolicy Always but no HTTPS in dev\nbuilder.Services.AddAntiforgery(o =>\n    o.Cookie.SecurePolicy = CookieSecurePolicy.Always);\n\n// after — honor forwarded headers behind TLS-terminating proxy\nbuilder.Services.Configure<ForwardedHeadersOptions>(o =>\n    o.ForwardedHeaders = ForwardedHeaders.XForwardedProto);\napp.UseForwardedHeaders();","handlingStrategy":"validation","validationCode":"// Check before calling antiforgery APIs\nif (_antiforgeryOptions.Cookie.SecurePolicy == CookieSecurePolicy.Always\n    && !httpContext.Request.IsHttps)\n{\n    // redirect to HTTPS or adjust SecurePolicy\n    return Redirect(\"https://\" + httpContext.Request.Host + httpContext.Request.Path);\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await _antiforgery.ValidateRequestAsync(httpContext);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"SSL\"))\n{\n    _logger.LogCritical(\"Antiforgery requires HTTPS but request is HTTP\");\n    return BadRequest(\"HTTPS is required.\");\n}","preventionTips":["Always run HTTPS in all environments, including local dev.","If behind a TLS-terminating proxy, configure UseForwardedHeaders with XForwardedProto.","Use CookieSecurePolicy.SameAsRequest if HTTPS isn't guaranteed (less secure)."],"tags":["antiforgery","security","ssl","https","configuration","reverse-proxy"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}