Back to Article List

Fix: SMTP not configured, check grafana.ini

Fix: SMTP not configured, check grafana.ini - Fix: SMTP not configured, check grafana.ini

The full message is "SMTP not configured, check your grafana.ini config file's [smtp] section". The first time I hit it I spent forty minutes rewriting the host and the port, and both had been correct the whole time. The message names the right file and points you at the wrong line inside it.

What the error means, from the Grafana source

The string is defined once, in pkg/services/notifications/models.go:

var ErrSmtpNotEnabled = errors.New("SMTP not configured, check your grafana.ini config file's [smtp] section")

And it is returned from exactly one place, a single guard in pkg/services/notifications/mailer.go:

if !ns.Cfg.Smtp.Enabled {
    return nil, ErrSmtpNotEnabled
}

That's the whole story. The message means one thing: Smtp.Enabled is false in the configuration the running process holds in memory. Grafana returns it before it resolves a hostname and long before it opens a socket. So a wrong host cannot produce it. Neither can a bad password, a certificate problem, a blocked port or a relay that rejects your sender. Those all happen later and produce different errors from the dialer, with words like dial tcp or x509 in them.

Checking your SMTP host and port cannot fix it. The question is why enabled is false when you are sure you set it to true.

Check the config the running process loaded

Settle this first, because it splits the problem in half. Grafana exposes its effective configuration, after every override layer has been applied, to a server admin:

curl -s -u admin:yourpassword http://localhost:3000/api/admin/settings | jq .smtp

That endpoint only accepts basic auth and only for a Grafana server administrator, and it redacts the password to a run of asterisks. The Grafana admin HTTP API reference documents the response shape. Same view in the browser under Administration, then General, then Settings, which is /admin/settings.

If enabled comes back "false" there, the file you edited is not reaching the process, and one of the seven reasons below is why. If it comes back "true", you are past this error entirely and whatever you're seeing now is a different failure, covered at the end.

No admin password to hand? Fall back to the file plus the startup log:

sudo grep -n -A 14 '^\[smtp\]' /etc/grafana/grafana.ini
sudo journalctl -u grafana-server -n 60 --no-pager

Seven reasons enabled is still false

The line is still commented out

This is the one, by a wide margin. The /etc/grafana/grafana.ini that ships with the package is a copy of conf/sample.ini, and every line in sample.ini starts with a semicolon. A leading semicolon is an INI comment. You open the file, find the [smtp] block sitting there looking configured, change false to true, and save a line that reads ;enabled = true.

That convention exists because sample.ini is documentation and configuration at the same time, so every key is present with its shipped default visible next to it. As a way to write a config file it is a good idea. It also produces this exact bug somewhere in the world about once a week.

Run the grep above and look at the left edge of every line. Strip the semicolon from the keys you're setting, and from the [smtp] header itself. A section header that's still a comment puts every key under it into whatever section came before.

You edited a different file from the one Grafana reads

Grafana reads one custom config file and the path depends on the install. On deb or rpm it's /etc/grafana/grafana.ini. On a tarball install it's conf/custom.ini, which you create yourself, and editing conf/defaults.ini instead is a common wrong turn: the docs say "Don't change this file", and it's overwritten on upgrade anyway. Homebrew puts it under /opt/homebrew/etc/grafana/ or /usr/local/etc/grafana/ depending on the CPU. On Windows you copy conf\sample.ini to conf\custom.ini.

Stop guessing and ask the process which file it was told to use:

ps -eo args | grep '[g]rafana' | head -1

The --config= argument in that output is the only file that matters. Every install layout is listed in where to set up Grafana SMTP settings, along with the full key reference. On Windows the separator is a backslash.

The process never sees that file

Containers and Kubernetes both do this to people. If you edited /etc/grafana/grafana.ini on the host and never mounted it into the container, the container is still using its own copy, which is sample.ini with everything commented out. Check inside:

docker exec grafana grep -A 3 '^\[smtp\]' /etc/grafana/grafana.ini

Under Helm the config comes from the grafana.ini key in your values file, rendered into a ConfigMap. Editing the file inside a running pod works until the pod restarts, at which point the chart writes its own version back. Fix it in values.yaml and upgrade the release. Environment variables are the cleaner route in both cases, and the Grafana Docker Compose setup shows the shape they take. The same keys go in a pod spec's env block.

Grafana was not restarted

Nothing watches the file. Grafana parses it when the process starts and never looks again.

sudo systemctl restart grafana-server

The systemd unit kept its old name even though the CLI binary is now the two-word grafana server, so grafana-server is right here. In Docker, note that changing an environment variable needs the container recreated, not restarted: docker compose up -d --force-recreate grafana. A plain docker restart reuses the existing environment and you'll swear the variable did nothing.

An environment variable is overriding the file

Environment variables outrank your config file. That is the whole mechanism here, and it is why a stale GF_SMTP_ENABLED=false sitting in a systemd drop-in or a compose file quietly beats the grafana.ini you just fixed. Nothing warns you.

sudo systemctl show grafana-server -p Environment -p EnvironmentFiles
docker exec grafana env | grep GF_SMTP

The full precedence chain, all five layers of it, is written out on the Grafana page for configuring Grafana. Reading it once removes most of the config surprises you will ever have with this software.

The section header is misspelled

[smpt] is easy to type and impossible to see. Putting enabled = true above the header does the same damage, since the key silently joins the preceding section. List the headers and read them:

sudo grep -n '^\[' /etc/grafana/grafana.ini

You want exactly one [smtp]. If a second one appears later in the file, left behind from an earlier attempt, the later block wins and it is usually the empty one. I have never worked out if that comes from the INI library or from Grafana's own loading, and it has never mattered enough to go and look.

The value has quotes or trailing whitespace

Type the value bare: enabled = true, nothing after it.

A line pasted out of a forum thread can carry a non-breaking space or a trailing tab that no editor shows you. Make it visible:

sudo sed -n '/^\[smtp\]/,/^\[/p' /etc/grafana/grafana.ini | cat -A | head -20

cat -A marks line ends with $ and tabs with ^I, so enabled = true$ is clean and enabled = true^I$ is your problem. Retype the line rather than trying to delete the invisible character.

Errors that appear after enabled = true

Once the flag is genuinely true, sending gets as far as the network and the errors change completely. None of the messages below is this article's error.

MessageWhat it means
dial tcp ...: i/o timeoutNothing is listening or something is filtering. A localhost:25 or :25 host is the usual culprit, since outbound 25 is shut by default on most hosting networks.
x509: certificate signed by unknown authorityNo CA bundle where Grafana is running. Common in minimal containers missing ca-certificates.
x509: certificate is valid for a.example.com, not b.example.comThe hostname in host doesn't match the relay's certificate. Use the name the provider documents, not an IP.
535 5.7.8 Username and Password not acceptedCredentials rejected. On Gmail this usually means a regular password where an app password is required.
gomail: invalid addressAn address failed to parse. Check from_address for a stray display name or angle brackets, and check the recipient list on the contact point.
invalid email address for SMTP from_address configRaised at startup by the notifications service when from_address isn't a valid address. It appears in the log, not in the UI.

Grep the log for that last one even when mail looks fine, because it fires during service initialisation and scrolls away fast. Where the log lives differs between a package install and a container, and where Grafana logs live covers both layouts. It is a five second check either way.

Test the connection without Grafana

When the error is a network or credential one, take Grafana out of the picture. Two commands settle it.

openssl s_client -starttls smtp -crlf -connect smtp.example.com:587

A hang means egress filtering or a firewall. A printed certificate chain and a 250 banner means the path is open and TLS negotiates, so the problem is authentication or sender identity. For a full send including the login:

sudo apt-get install -y swaks
swaks --to [email protected] --from [email protected] \
  --server smtp.example.com:587 --tls \
  --auth LOGIN --auth-user [email protected]

swaks prompts for the password and prints the entire SMTP conversation, so you see the exact response code the relay gives. If swaks delivers a message and Grafana still won't, the difference is in the config values. The Grafana troubleshooting docs and the roundup of common Grafana errors cover what is left of the list. With enabled true and a test send landing, the next thing to build is the contact point and the rules behind it, which is setting up email alerts in Grafana.

Your idea deserves better hosting

24/7 support 30-day money-back guarantee Cancel anytime
Billing Cycle

VPS.S1

22.26 zł Save  17 %
18.54 Monthly
  • 2 vCPU AMD EPYC
  • 2 GB RAMMEMORY
  • 30 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included

VPS.S3

55.83 zł Save  33 %
37.21 Monthly
  • 4 vCPU AMD EPYC
  • 6 GB RAMMEMORY
  • 70 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included

EPYC VPS.P1

33.48 zł Save  22 %
26.04 Monthly
  • 2 vCPU AMD EPYC
  • 4 GB RAMMEMORY
  • 40 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P2

63.28 zł Save  24 %
48.38 Monthly
  • 2 vCPU AMD EPYC
  • 8 GB RAMMEMORY
  • 80 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P4

111.70 zł Save  23 %
85.63 Monthly
  • 4 vCPU AMD EPYC
  • 16 GB RAMMEMORY
  • 160 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P5

148.59 zł Save  25 %
111.43 Monthly
  • 8 vCPU AMD EPYC
  • 16 GB RAMMEMORY
  • 180 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P6

223.44 zł Save  25 %
167.57 Monthly
  • 8 vCPU AMD EPYC
  • 32 GB RAMMEMORY
  • 200 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P7

260.05 zł Save  29 %
185.74 Monthly
  • 16 vCPU AMD EPYC
  • 32 GB RAMMEMORY
  • 240 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

Genoa VPS.G2

92.85 zł Save  20 %
74.28 Monthly
  • 2 vCPUAMD EPYC Genoa 4th generation 9xx4 with 3.25 GHz or similar, on Zen 4 architecture. AMD EPYC G4
  • 4 GB DDR5MEMORY
  • 50 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

Genoa VPS.G4

167.16 zł Save  22 %
130.01 Monthly
  • 4 vCPUAMD EPYC processor with dedicated vCPU cores, on enterprise server hardware. AMD EPYC G4
  • 8 GB DDR5MEMORY
  • 100 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

Genoa VPS.G6

334.37 zł Save  22 %
260.05 Monthly
  • 8 vCPUAMD EPYC processor with dedicated vCPU cores, on enterprise server hardware. AMD EPYC G4
  • 16 GB DDR5MEMORY
  • 200 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

Genoa VPS.G7

594.46 zł Save  22 %
464.41 Monthly
  • 8 vCPUAMD EPYC processor with dedicated vCPU cores, on enterprise server hardware. AMD EPYC G4
  • 32 GB DDR5MEMORY
  • 250 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

AMD Ryzen VPS.R1

63.13 zł Save  18 %
51.98 Monthly
  • 1 dedicated CPU AMD Ryzen 9 7950X with 4.5 GHz or similar, on Zen 4 architecture. vCPU
  • 4 GB DDR5MEMORY
  • 50 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6 included IPv6 support is currently unavailable in France, Finland or the Netherlands.
  • Auto backup included

AMD Ryzen VPS.R2

111.43 zł Save  17 %
92.85 Monthly
  • 2 dedicated CPUs AMD Ryzen 9 7950X with 4.5 GHz or similar, on Zen 4 architecture. vCPU
  • 8 GB DDR5MEMORY
  • 100 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6 included IPv6 support is currently unavailable in France, Finland or the Netherlands.
  • Auto backup included

AMD Ryzen VPS.R4

408.68 zł Save  18 %
334.37 Monthly
  • 8 dedicated CPUs AMD Ryzen 9 7950X with 4.5 GHz or similar, on Zen 4 architecture. vCPU
  • 32 GB DDR5MEMORY
  • 400 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6 included IPv6 support is currently unavailable in France, Finland or the Netherlands.
  • Auto backup included

Frequently asked questions

Does setting skip_verify = true fix "SMTP not configured"?

No, and it can't. skip_verify controls certificate validation on a TLS connection that this error prevents Grafana from ever opening. The check on enabled runs before any network activity. Turning off certificate verification to chase this message leaves you with a weaker TLS config and the same error. It is a legitimate setting for a relay using a self-signed certificate, which is a different problem.