Skip to content
Latchkey

Mailgun 401 Forbidden (bad API key) in CI

Mailgun returns HTTP 401 with the body Forbidden when the basic-auth credentials are wrong. The messages API expects HTTP basic auth with username api and the private API key as the password. A missing key, a rotated key, or the wrong username all fail.

What this error means

A Mailgun messages request returns HTTP 401 with body Forbidden. No email is sent from the CI step.

Mailgun API
< HTTP/1.1 401 UNAUTHORIZED
Forbidden

Common causes

The API key is missing or rotated

The MAILGUN_API_KEY secret is empty or holds an old key that was regenerated.

Wrong basic-auth username

Mailgun requires the literal username api; using anything else returns Forbidden.

How to fix it

Authenticate with api and the private key

  1. Copy the private API key (or a domain sending key) from the Mailgun dashboard.
  2. Store it as the MAILGUN_API_KEY secret.
  3. Send basic auth as api:$MAILGUN_API_KEY.
Terminal
curl -sS --user "api:$MAILGUN_API_KEY" \
  https://api.mailgun.net/v3/$MAILGUN_DOMAIN/messages \
  -F from='CI <ci@your-domain.com>' \
  -F to='team@example.com' \
  -F subject='build passed' -F text='ok'

Check the region host

EU-region domains use api.eu.mailgun.net; using the US host for an EU key can also read as unauthorized.

URL
https://api.eu.mailgun.net/v3/$MAILGUN_DOMAIN/messages

How to prevent it

  • Store the sending key in a CI secret and rotate both together.
  • Always use the literal api username for basic auth.
  • Match the API host to the domain region (US vs EU).

Frequently asked questions

What causes "Mailgun 401 Forbidden"?
The MAILGUN_API_KEY secret is empty or holds an old key that was regenerated.
How do I fix Mailgun 401 Forbidden?
Authenticate with api and the private key

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card