I ran this command:
private async Task<OrderInfo> CreateLE(string host, string account, Func<string, string, Exception, Task> failFunc, Func<string, Task> successFunc, int timeoutMs, CancellationToken cancellationToken)
{
if (!HostHelper.IsDomain(host))
{
try { await failFunc($"Invalid domain {host}", host, null); } catch { }
return null;
}
cancellationToken.ThrowIfCancellationRequested();
var acme = new AcmeContext(_options.AcmeServer, KeyFactory.FromPem(account));
_Log.Information("Lets Encrypt: Creating order for {Host}", host);
cancellationToken.ThrowIfCancellationRequested();
var order = await acme.NewOrder(new[] { host });
cancellationToken.ThrowIfCancellationRequested();
var authzs = (await order.Authorizations());
var authz = authzs.First();
var httpChallenge = await authz.Http();
var orderInfo = new OrderInfo
{
Order = order,
Challenge = httpChallenge,
HostName = host,
FailFunc = failFunc,
SuccessFunc = successFunc,
CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, new CancellationTokenSource(timeoutMs).Token)
};
_ = Task.Run(async () => await orderInfo.TimeoutMonitorAsync());
cancellationToken.ThrowIfCancellationRequested();
_httpChallengeResponseStore.AddChallengeResponse(httpChallenge.Token, orderInfo);
cancellationToken.ThrowIfCancellationRequested();
await httpChallenge.Validate();
// Even if the challenges never come, attempt to finish creating the certificate after 30 seconds.
// We do this because, if you request a duplicate certificate within a certain time period, there will be no
// new challenges issued by Let's Encrypt.
await Task.Run(async () =>
{
// Give some time to Let´s Encrypt to send challenges and process our responses.
await Task.Delay(30 * 1000, orderInfo.CancellationTokenSource.Token);
if (!orderInfo.CancellationTokenSource.Token.IsCancellationRequested)
{
await BuildCertificate(orderInfo, orderInfo.HostName);
}
else
{
await orderInfo.FailedAsync($"Domain validation cancelled for {orderInfo.HostName}", orderInfo.HostName, null);
}
});
return orderInfo;
}
It produced this output:
2026-02-09 11:38:15.023 -06:00 [FTL] (XA418/8) Application terminated unexpectedly
System.AggregateException: One or more errors occurred. (Can not finalize order with status 'Invalid'.)
---> Certes.AcmeException: Can not finalize order with status 'Invalid'.
at Certes.IOrderContextExtensions.Generate(IOrderContext context, CsrInfo csr, IKey key, String preferredChain, Int32 retryCount)
at LetsEncrypt.CertificateRequestor.BuildCertificate(OrderInfo orderInfo, String hostName)
at LetsEncrypt.CertificateRequestor.BuildCertificate(OrderInfo orderInfo, String hostName)
at LetsEncrypt.CertificateRequestor.<>c__DisplayClass22_0.<<CreateLE>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at LetsEncrypt.CertificateRequestor.CreateLE(String host, String account, Func`4 failFunc, Func`2 successFunc, Int32 timeoutMs, CancellationToken cancellationToken)
at LetsEncrypt.CertificateRequestor.<>c__DisplayClass15_0.<<RefreshCertificates>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at LetsEncrypt.CertificateRequestor.<>c__DisplayClass15_0.<<RefreshCertificates>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at LetsEncrypt.SemaphoreLock.TryLockAsync(Int32 timeoutMs, Func`1 worker)
at LetsEncrypt.CertificateRequestor.RefreshCertificates(Func`4 failFunc, Func`2 successFunc, Int32 timeoutMs, CancellationToken cancellationToken)
at LetsEncrypt.DomainManager.SetActive(DomainInfo[] domains, Func`4 failFunc, Func`2 successFunc, Func`2 preFunc, Func`2 postFunc, Int32 timeoutMs, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at LetsEncrypt.Extensions.UseLetsEncrypt(IApplicationBuilder app, IServiceProvider serviceProvider, DomainInfo[] domains, Func`2 preFunc, Func`2 postFunc)
at FaceFirst.LetsEncrypt.LetsEncryptExtensions.UseFaceFirstLetsEncrypt(IApplicationBuilder app, IServiceProvider serviceProvider, DomainInfo[] domains, Func`2 preFunc, Func`2 postFunc)
at FaceFirst.Deployment.Server.Program.Main(String[] args)
My web server is (include version): Kestral
The operating system my web server runs on is (include version): Windows Server 2019 Standard
My hosting provider, if applicable, is: WebNx
I can login to a root shell on my machine (yes or no, or I don't know): Yes
I'm using a control panel to manage my site (no, or provide the name and version of the control panel): No
The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): We are not using the Certbot
We have this legacy app where there is a middleware C# package that we use to manage our certificates when used via Let's Encrypt.
That we have not changed in years.