aspnetcore: crit: Microsoft.AspNetCore.Server.Kestrel[0] Unable to start Kestrel

I developed my asp.net core application in windows, and move to a container where it is working perfectly in my local environment with https. But now i want to run my application with https in Ubuntu 18.04, but i am getting error, i am providing our own certificate but it is not working. The error is given below. I am running applications via docker-compose. Docker-compose and other required files are also given below. Please help me to solve this issue

> WebPortal      | Unhandled Exception: Interop+Crypto+OpenSslCryptographicException: error:2006D080:BIO routines:BIO_new_file:no such file
WebPortal      |    at Interop.Crypto.CheckValidOpenSslHandle(SafeHandle handle)
WebPortal      |    at Internal.Cryptography.Pal.CertificatePal.FromFile(String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
WebPortal      |    at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
WebPortal      |    at TT.Core.Web.Program.<>c__DisplayClass1_0.<CreateWebHostBuilder>b__1(ListenOptions listenOptions) in /src/TT.Core.Web/Program.cs:line 56
WebPortal      |    at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPEndPoint endPoint, Action`1 configure)
WebPortal      |    at TT.Core.Web.Program.<>c.<CreateWebHostBuilder>b__1_0(KestrelServerOptions options) in /src/TT.Core.Web/Program.cs:line 68
WebPortal      |    at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
WebPortal      |    at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
WebPortal      |    at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
WebPortal      |    at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
WebPortal      |    at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
WebPortal      |    at System.Lazy`1.CreateValue()
WebPortal      |    at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
WebPortal      |    at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
WebPortal      |    at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
WebPortal      |    at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.CreateServiceContext(IOptions`1 options, ILoggerFactory loggerFactory)
WebPortal      |    at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer..ctor(IOptions`1 options, ITransportFactory transportFactory, ILoggerFactory loggerFactory)
WebPortal      | --- End of stack trace from previous location where exception was thrown ---
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProviderEngineScope scope)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
WebPortal      |    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
WebPortal      |    at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureServer()
WebPortal      |    at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
WebPortal      |    at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
WebPortal      |    at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
WebPortal      |    at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
WebPortal      |    at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
WebPortal      |    at TT.Core.Web.Program.Main(String[] args) in /src/TT.Core.Web/Program.cs:line 32
WebPortal exited with code 139



Docker-compose.yml

version: ‘3.4’

services:

tt.core.web:

image: thingtraxcontainerregistry.azurecr.io/ttcoreweb

container_name: WebPortal

environment:

  CORE_ENVIRONMENT: ${env}

  ASPNETCORE_ENVIRONMENT: ${env}

  IsDockerDeployment: ${isDockerDeployment}

restart: always

networks:

 - app-network

networks:

app-network:

ipam:

  driver: default

  config:

    - subnet: 172.24.0.0/16

docker-compose.override.yml

version: ‘3.4’

services:

tt.core.web:

environment:

  - ASPNETCORE_ENVIRONMENT=${env}

  - IsDockerDeployment=${isDockerDeployment}

  - ASPNETCORE_URLS=https://+:443;http://+:80

  - ASPNETCORE_HTTPS_PORT=443

  - KestrelPath=${appCertificate}

  - KestrelPassword=${appCertificatepassword}

  - ASPNETCORE_Kestrel__Certificates__Default__Password=doaminnamepassword

  - ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/_.domainname.com_private_key.pfx

ports:

  - "80:80"

  - "443:443"

volumes:

  - /home/thingtrax/Downloads/DockerComposelinux/DockerCompose/config:/root/.aspnet/https:ro

  - /home/thingtrax/Downloads/DockerComposelinux/DockerCompose/config:/root/.microsoft/usersecrets:ro

.env file

env=devdocker isDockerDeployment=true appCertificate=/root/.aspnet/https/_.domainname.com_private_key.pfx appCertificatepassword=doaminnamepassword.123!

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (8 by maintainers)

Most upvoted comments

The problem has been resolved by following your last recommendation regarding app-settings @Tratcher @halter73 I am grateful for your support.

It’s wherever your configuration is defined. https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

CreateDefaultBuilder will load config from appsettings.json and appsettings.{Environment}.json by default.

Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadDefaultCert(ConfigurationReader configReader)

This last stack trace is subtly different than the original. The exception is no longer being thrown from inside your KestrelServerOptions.Listen callback and is instead being throw when Kestrel is loading config.

Do you have a section like the following in your configuration defining a default certificate? And if so, does it specify the path to a valid certificate in your docker container? Even if the certificate is not actually used, Kestrel will try to load it.

{
  "Kestrel": {
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "<certificate password>"
      }
    }
  }
}

System.IO.IOException: Read-only file system

It should probably be File.Open(certPath, FileMode.Open, FileAccess.Read) instead of File.Open(certPath, FileMode.Open) then. I’m just trying to verify the cert file exists when the server starts.

@bilalmalik777 thanks for the additional details.

I think your .env file looks wrong? I can’t tell for sure, but you have doaminnamepassword above and doaminnamepassword.123! not sure if that matters.

I’m not a docker compose expert, but that feels like an issue.

You can try modifying your app to make sure that you can get the config keys and that the file exists when you run docker compose, just to discard a config issue.

It might also be good if you check the pfx password is correct with openssl pkcs12 -in mypfx.pfx -noout

@bilalmalik777 thanks for contacting us.

As @Tratcher points out, the issue is that your app is failing to find the certificate. I think the issue is that you are missing a mapping or something like that.

I would recommend connecting to the running container with docker exec -it /bin/bash and checking to make sure that the files are in the right place. You might not have exported the certificate.

Also note that the locations you are using are the ones that our “tooling” uses and that if you are driving things from the command-line it might be simpler for you to simply export the cert to somewhere more convenient and pass in the file path and the password. There is no need for you to map the user secrets folder unless you are using it for something else.

It can’t find the certificate?

How was the docker compose file generated?

@javiercn ?