I’m setting up a new Discourse instance on a friend’s Google Compute Engine VPS running Arch. Things went pretty well, except for SMTP. (Side note: although I’m using a friend’s VPS, this Discourse instance is for me, not him. He’s just providing hosting.) I already had a Discourse instance working perfectly on a DigitalOcean droplet running CentOS 7 a few days ago, but… he nuked the VPS out of rage because of community drama. So I had to move the site to a new server hosted by someone I actually know and trust.
I’m using the exact same SparkPost credentials and SMTP config that I did on the previous box, only difference being I’m using port 2525. GCE blocks 25, 465 and 587.
I’m stuck at the “Finish Installation” screen, the part where I set up my admin account, select the theme, emoji pack, etc. I’m not receiving my confirmation email. I performed the usual troubleshooting steps - checked config, it’s good. Checked SparkPost, no messages were being registered as even “rejected” - indicating a connection error between SparkPost and Discourse.
Sure enough, I look in my production.log and I’m getting
Job exception: end of file reached
directly after all attempts to send mail.
My next troubleshooting step involved writing a quick C# program that uses my SparkPost configuration settings and
System.Net.Mail.SmtpClient to send a test email that confirms that the email is actually deliverable. I used the exact same config as I have in Discourse. I ran the program three times.
Once, in my development environment where I wrote the program. Second time was through Mono on Arch Linux, on the computer running the Docker container that Discourse is in. The third time was actually in the Docker Container by copying the .exe file into the
/var/discourse/shared/standalone folder on the host, then running
sudo /var/discourse/launcher enter app # in container apt-get install mono-complete # now I have .NET Framework cd /shared mono SMTPTestUtility.exe
On my Windows development environment, and on the Docker host, the program succeeded - it simply printed “Done”, waited for a keypress, and exited. As soon as it said “Done”, the test message appeared in my inbox. Both times.
However, I programmed it to print out a FULL stack trace and any and all error messages before exiting if the program experiences an error at all. Thank God I did, because when I ran the program inside the Docker container, this was its output.
root@archlinux-app:/shared# mono smtp.exe System.Net.Mail.SmtpException: Message could not be sent. ---> System.IO.IOException: The authentication or decryption has failed. ---> System.IO.IOException: The authentication or decryption has failed. ---> System.InvalidOperationException: SSL authentication error: RemoteCertificateNotAvailable, RemoteCertificateChainErrors at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (IAsyncResult asyncResult) <0x41e76ea0 + 0x000ff> in <filename unknown>:0 at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (IAsyncResult ar, Boolean ignoreEmpty) <0x41e76de0 + 0x0002b> in <filename unknown>:0 at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (IAsyncResult result) <0x41e72000 + 0x00213> in <filename unknown>:0 --- End of inner exception stack trace --- at Mono.Security.Protocol.Tls.SslClientStream.EndNegotiateHandshake (IAsyncResult result) <0x41e8e830 + 0x000bf> in <filename unknown>:0 at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) <0x41e8e5d0 + 0x0007f> in <filename unknown>:0 --- End of inner exception stack trace --- at Mono.Security.Protocol.Tls.SslStreamBase.EndRead (IAsyncResult asyncResult) <0x41e703b0 + 0x00153> in <filename unknown>:0 at System.Net.Security.SslStream.EndAuthenticateAsClient (IAsyncResult asyncResult) <0x41e70310 + 0x0003e> in <filename unknown>:0 at System.Net.Security.SslStream.AuthenticateAsClient (System.String targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation) <0x41e693f0 + 0x00055> in <filename unknown>:0 at System.Net.Mail.SmtpClient.InitiateSecureConnection () <0x41e68f20 + 0x000df> in <filename unknown>:0 at System.Net.Mail.SmtpClient.SendCore (System.Net.Mail.MailMessage message) <0x41e66500 + 0x0020f> in <filename unknown>:0 at System.Net.Mail.SmtpClient.SendInternal (System.Net.Mail.MailMessage message) <0x41e5da00 + 0x00207> in <filename unknown>:0 at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) <0x41e5d670 + 0x00113> in <filename unknown>:0 --- End of inner exception stack trace --- at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) <0x41e5d670 + 0x001c7> in <filename unknown>:0 at System.Net.Mail.SmtpClient.Send (System.String from, System.String to, System.String subject, System.String body) <0x41e5c1c0 + 0x00063> in <filename unknown>:0 at SMTPTestUtility.Program.Main (System.String args) <0x41e32d50 + 0x000eb> in <filename unknown>:0 Done.
So obviously it’s not a Discourse configuration issue. But given this issue is preventing me from using Discourse, I thought I’d post it here. Maybe there’s something useful in that C# stacktrace that just wouldn’t show in the Discourse production.log. The most I know is it’s an SSL certificate error. Given it only happens inside the Docker container, maybe there’s some weird issue with it?
Any help would be greatly appreciated.