Wrong host or port when configuring Email

I am trying to configure Email for our Metabase instance, such that users can do password recovery, receive notification, etc.

The information I received about our SMTP server is as follow (this information is verified to be correct):
SMTP hostname: myorg-com.mail.protection.outlook.com
SMTP port: 25

Of course I changed my real organization's name to 'myorg.' I input both of the above without authentication (SMTP username and password) since none is required according to our IT admin. However, Metabase did not accept the input, it returned the error 'Wrong host or port.' I am sure that the above host and port are correct.

Hi @daniel11
Post "Diagnostic Info" from Admin > Troubleshooting.
And the full stacktrace from Admin > Troubleshooting > Logs.
I'm guessing that you're trying to use relay: https://docs.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365#settings-for-microsoft-365-or-office-365-smtp-relay

I'm just at the stage of filling in the forms on the Email config page. But yes, I was also looking at the microsoft docs link you just posted.

Diagnostic Info:

{
"browser-info": {
"language": "en-US",
"platform": "Linux x86_64",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
"vendor": "Google Inc."
},
"system-info": {
"file.encoding": "UTF-8",
"java.runtime.name": "OpenJDK Runtime Environment",
"java.runtime.version": "11.0.15+10",
"java.vendor": "Eclipse Adoptium",
"java.vendor.url": "https://adoptium.net/",
"java.version": "11.0.15",
"java.vm.name": "OpenJDK 64-Bit Server VM",
"java.vm.version": "11.0.15+10",
"os.name": "Linux",
"os.version": "5.10.118-111.515.amzn2.x86_64",
"user.language": "en",
"user.timezone": "GMT"
},
"metabase-info": {
"databases": [
"h2",
"csv"
],
"hosting-env": "unknown",
"application-database": "h2",
"application-database-details": {
"database": {
"name": "H2",
"version": "1.4.197 (2018-03-18)"
},
"jdbc-driver": {
"name": "H2 JDBC Driver",
"version": "1.4.197 (2018-03-18)"
}
},
"run-mode": "prod",
"version": {
"date": "2022-06-27",
"tag": "v0.43.4",
"branch": "release-x.43.x",
"hash": "61cc28e"
},
"settings": {
"report-timezone": null
}
}
}

Logs from Troubleshooting (I only copied the parts that seem relevant. Changed my org's name to 'myownorg'):

com.sun.mail.util.MailConnectException: Couldn't connect to host, port: myownorg-com.mail.protection.outlook.com, 25; timeout 1000;
nested exception is:
java.net.SocketTimeoutException: connect timed out
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2210)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:722)
at javax.mail.Service.connect(Service.java:342)
at metabase.email$fn__57280$test_smtp_settings__57285$fn__57289$fn__57292.invoke(email.clj:158)
at metabase.email$fn__57280$test_smtp_settings__57285$fn__57289.invoke(email.clj:157)
at metabase.email$fn__57280$test_smtp_settings__57285.invoke(email.clj:141)
at metabase.email$fn__57337$test_smtp_connection__57342$fn__57343.invoke(email.clj:205)
at metabase.email$fn__57337$test_smtp_connection__57342.invoke(email.clj:189)
at metabase.api.email$fn__62904.invokeStatic(email.clj:80)
at metabase.api.email$fn__62904.invoke(email.clj:69)
at compojure.core$wrap_response$fn__28036.invoke(core.clj:160)
at compojure.core$wrap_route_middleware$fn__28020.invoke(core.clj:132)
at compojure.core$wrap_route_info$fn__28025.invoke(core.clj:139)
at compojure.core$wrap_route_matches$fn__28029.invoke(core.clj:151)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__28029.invoke(core.clj:153)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048.invoke(core.clj:200)
at metabase.server.middleware.auth$enforce_authentication$fn__66770.invoke(auth.clj:14)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048.invoke(core.clj:200)
at compojure.core$make_context$handler__28076.invoke(core.clj:289)
at compojure.core$make_context$fn__28080.invoke(core.clj:299)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$make_context$fn__28080.invoke(core.clj:300)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at metabase.api.routes$fn__78132$fn__78135.invoke(routes.clj:59)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048.invoke(core.clj:200)
at clojure.lang.AFn.applyToHelper(AFn.java:160)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$apply.invoke(core.clj:662)
at metabase.server.routes$fn__78282$fn__78283.doInvoke(routes.clj:67)
at clojure.lang.RestFn.invoke(RestFn.java:436)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048.invoke(core.clj:200)
at compojure.core$make_context$handler__28076.invoke(core.clj:289)
at compojure.core$make_context$fn__28080.invoke(core.clj:299)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__28029.invoke(core.clj:153)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__28029.invoke(core.clj:153)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__28029.invoke(core.clj:153)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050.invoke(core.clj:197)
at metabase.server.routes$fn__78268$fn__78270.invoke(routes.clj:45)
at compojure.core$routes$fn__28048$f__28049.invoke(core.clj:198)
at compojure.core$routes$fn__28048.invoke(core.clj:200)
at metabase.server.middleware.exceptions$catch_uncaught_exceptions$fn__75094.invoke(exceptions.clj:98)
at metabase.server.middleware.exceptions$catch_api_exceptions$fn__75091.invoke(exceptions.clj:86)
at metabase.server.middleware.log$log_api_call$fn__78752$fn__78753$fn__78754.invoke(log.clj:211)
at metabase.driver.sql_jdbc.execute.diagnostic$do_with_diagnostic_info.invokeStatic(diagnostic.clj:15)
at metabase.driver.sql_jdbc.execute.diagnostic$do_with_diagnostic_info.invoke(diagnostic.clj:9)
at metabase.server.middleware.log$log_api_call$fn__78752$fn__78753.invoke(log.clj:203)
at toucan.db$_do_with_call_counting.invokeStatic(db.clj:216)
at toucan.db$_do_with_call_counting.invoke(db.clj:209)
at metabase.server.middleware.log$log_api_call$fn__78752.invoke(log.clj:202)
at metabase.server.middleware.browser_cookie$ensure_browser_id_cookie$fn__81988.invoke(browser_cookie.clj:38)
at metabase.server.middleware.security$add_security_headers$fn__60363.invoke(security.clj:148)
at metabase.server.middleware.json$wrap_json_body$fn__81127.invoke(json.clj:63)
at metabase.server.middleware.json$wrap_streamed_json_response$fn__81145.invoke(json.clj:99)
at metabase.server.middleware.offset_paging$handle_paging$fn__60387.invoke(offset_paging.clj:42)
at ring.middleware.keyword_params$wrap_keyword_params$fn__82255.invoke(keyword_params.clj:55)
at ring.middleware.params$wrap_params$fn__82274.invoke(params.clj:77)
at metabase.server.middleware.misc$maybe_set_site_url$fn__35185.invoke(misc.clj:59)
at metabase.server.middleware.session$bind_current_user$fn__46657$fn__46658.invoke(session.clj:291)
at metabase.server.middleware.session$do_with_current_user.invokeStatic(session.clj:270)
at metabase.server.middleware.session$do_with_current_user.invoke(session.clj:259)
at metabase.server.middleware.session$bind_current_user$fn__46657.invoke(session.clj:290)
at metabase.server.middleware.session$wrap_current_user_info$fn__46639.invoke(session.clj:240)
at metabase.server.middleware.session$wrap_session_id$fn__46623.invoke(session.clj:173)
at metabase.server.middleware.auth$wrap_api_key$fn__66778.invoke(auth.clj:27)
at ring.middleware.cookies$wrap_cookies$fn__82175.invoke(cookies.clj:216)
at metabase.server.middleware.misc$add_content_type$fn__35168.invoke(misc.clj:27)
at metabase.server.middleware.misc$disable_streaming_buffering$fn__35193.invoke(misc.clj:76)
at ring.middleware.gzip$wrap_gzip$fn__82217.invoke(gzip.clj:86)
at metabase.server.middleware.misc$bind_request$fn__35196.invoke(misc.clj:93)
at metabase.server.middleware.ssl$redirect_to_https_middleware$fn__82004.invoke(ssl.clj:38)
at metabase.server$async_proxy_handler$fn__78524.invoke(server.clj:73)
at metabase.server.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle(Unknown Source)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:400)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:645)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:392)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketTimeoutException: connect timed out
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.base/java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.base/java.net.SocksSocketImpl.connect(Unknown Source)
at java.base/java.net.Socket.connect(Unknown Source)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:333)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:214)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2160)
... 128 more
[ec24ce70-6d5f-4e51-ac36-74c954d7ec4a] 2022-07-25T15:24:02+07:00 ERROR metabase.email Error testing SMTP connection
TOO LONG SO I DELETED AROUND HERE. IF NOT, THEN THIS REPLY WOULD CONTAIN MORE THAN 3 LINKS, THUS CANNOT BE POSTED.
... 133 more
[ec24ce70-6d5f-4e51-ac36-74c954d7ec4a] 2022-07-25T15:24:05+07:00 WARN metabase.api.email Problem connecting to mail server: Couldn't connect to host, port: myownorg-com.mail.protection.outlook.com, 25; timeout 1000: connect timed out
[ec24ce70-6d5f-4e51-ac36-74c954d7ec4a] 2022-07-25T15:24:05+07:00 DEBUG metabase.server.middleware.log PUT /api/email 400 5.7 s (0 DB calls)
{:errors {:email-smtp-host "Wrong host or port", :email-smtp-port "Wrong host or port"}}

@daniel11 And you can connect if you do this from the host running Metabase?
telnet myownorg-com.mail.protection.outlook.com 25
I'm not sure what Microsoft means with third-party, but try using client submission instead:
https://docs.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365#compare-the-options
We've just fixed some issues that occurred mostly on Outlook365, which will be part of v0.44:
https://github.com/metabase/metabase/pull/23921

I do not have access to the host running Metabase, I can only access the Metabase instance on it. So I cannot check if I can telnet into my org's SMTP server from there or not. However, I can telnet into my org's SMTP just fine from my PC, if that info helps somehow.

Anyway, by using client submission, do you mean inputting these into the Email config form?
SMTP Host: smtp.office365.com
SMTP Port: 587/25
Security: TLS
Username: blank (I had no idea what to input here)
Password: blank (I had no idea what to input here)
From Address: my.email@myorg.com

If yes, then I already did so. However, I got the error: Sorry, something went wrong. Please try again. Error: Can't send command to SMTP host: Connection or outbound has closed

@daniel11 Client submission requires user/pass. Try running Metabase locally on your computer as test.
Also, you should not use H2 if you're setting Metabase up for production:
https://www.metabase.com/docs/latest/operations-guide/migrating-from-h2.html

Pardon the question, but how/where do I obtain username and password to fill in the form?

Never mind, I got it to work now. Thanks!

@daniel11 Can you explain exactly what you did, so others can learn from it if they have the same problem?

For now, I am using Option 1 in here as suggested. And it works, nice! https://docs.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365

SMTP Host: smtp.office365.com
SMTP Port: 587
SMTP Security: TLS
Username: create a @outlook.com mail and input it here.
Password: password of the above @outlook.com mail
From address: the above email address

Basically, I using a personal email instead. It works for now, but in the long run I would want to use my organization's SMTP server. Unfortunately, it does not currently work.

Take a look at smtp2go.com. You'll need access to your company's DNS entries to configure properly but much easier to setup than fighting with office 365.

Update: I successfully configure Metabase to send recovery emails via my organization's SMTP server (e.g. myorglol.mail.protection.outlook.com:25).

What happened was: AWS blocks traffics on port 25 by default. Since our Metabase is housed within an AWS EC2 instance, it cannot connect to my organization's SMTP server via port 25. Thus I sent a request to AWS, asking for removal of restrictions on port 25. After those limits are lifted, connected to said SMTP server via port 25 was successful.

That was all. Took me some telnet attempts from my own PC, and from the concerning EC2 instance to figure out that AWS was restricting traffics on port 25.