Using MailGun Europe with Rails’s ActionMailer.

You’d think this isn’t worth a blogpost, since Mailgun has a dedicated mailgun-ruby gem for sending emails and it integrates well with Rails’s ActionMailer. However when setting this up last night a couple of errors were thrown my way that took some time to resolve.

Mailgun::ParseError (765: unexpected token at ‘Mailgun Magnificent API’)

First, when setting up a new Mailgun domain, it will ask you what language you’re using and shows an API key and a URL to use for sending emails.

In Rails the ActionMailer config in config/environments/production.rb looks like this:

  config.action_mailer.mailgun_settings = {
    :api_key => <your_api_key>,
    :domain => <your_domain>,

If you enter the full url from the Mailgun page in the domain field, Mailgun will return a Mailgun::ParseError (765: unexpected token at 'Mailgun Magnificent API') error. You have to change the domain to your sending domain (e.g.

Mailgun API response 404 (NOT FOUND)

Second if you selected Europe as the region for your new domain, and you fixed the issue above, you’ll get a new error along the lines of Mailgun API response 404 (NOT FOUND).

What’s happening is that the API can’t find your credentials/domain, since it’s hosted in another region.

Now the Gem documentation doesn’t mention this (yet, multiple pulls have been made, but somehow none have been merged yet).

You have to specify a 3rd parameter to the ActionMailer config, api_url that points to the Europe region API.

Your config/environments/production.rb should contain something like:

  config.action_mailer.delivery_method = :mailgun
  config.action_mailer.mailgun_settings = {
    :api_key => <your_api_key>,
    :domain => <your_domain>, # e.g.
    :api_host => ""

And of course we use ENV vars in production:

  config.action_mailer.delivery_method = :mailgun
  config.action_mailer.mailgun_settings = {
    :api_key => ENV["MAILGUN_API_KEY"],
    :domain => ENV["MAILGUN_DOMAIN"],
    :api_host => ""

With these two fixes applied and deployed, emails were flowing again \o/.

More posts

Switching to Svelte

I have rewritten my middleman site to Svelte/SvelteKit, here's what I encountered.

Remote uploads with pre-signed URLs on Scaleway's object storage.

Or, make sure your headers match, otherwise you'll get a lot of strange errors.

Upload a file to an AWS pre-signed S3 url with RestClient.

Or, how something so simple cost me so much time.

Publish articles from iA Writer to your static site.

My hope with this project is that with less friction to write and publish a note/article, I'll do it more.


Kafka and Ruby, a Sidekiq lovestory

In today's article, we’ll cover performance from a different angle: The choices we made in our stack for AppSignal.