Skip to main content

MY.L6.TIME_ZONE_TABLES_EMPTY — a named zone the server cannot resolve

  • Category: safety
  • Level: 6
  • Confidence: deterministic
  • Downtime class: none
  • Stability: stable
  • Suites: audit
  • Applies to: MySQL 8.4
  • Not transferable to MariaDB: this page describes MySQL 8.4 behavior. MariaDB answers the same driver and does not share these semantics, so SQLens refuses it outright rather than reasoning about it — see drivers/unsupported.

Named time zones live in tables in the mysql schema. A fresh MySQL install ships those tables empty — they are populated by running mysql_tzinfo_to_sql once, as an administrator.

Measured on a real MySQL 8.4 with the tables empty:

SELECT CONVERT_TZ('2026-01-01 14:00:00', 'UTC', '+00:00');
-- NULL

It does not raise. A query that looks correct silently produces nothing.

Why the trigger is narrower than it looks

Also measured: with the tables empty, the server refuses to adopt a named zone.

SET time_zone = 'Europe/Vienna';
-- ERROR 1298 (HY000): Unknown or incorrect time zone: 'Europe/Vienna'

So this state does not arise by setting the value. It arises the other way round — when a server that had the tables loses them:

  • a mysql schema restored from a dump that omitted them,
  • an upgrade that did not re-import,
  • a container image rebuilt without the step.

That makes the finding rare, and rare is exactly why it is worth keeping. A state nobody checks for is the one that survives to production.

Flagged

SELECT COUNT(*) FROM mysql.time_zone_name;
-- 0, while @@global.time_zone names a zone

Preferred

-- run once, as an administrator, against the server's own tzdata:
-- mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
SELECT COUNT(*) FROM mysql.time_zone_name;
-- a few hundred

Or move the server to the offset form (+00:00), which needs nothing loaded — see MY.L6.TIME_ZONE_NOT_UTC, which is why that rule prefers it.

Why this is a separate rule

MY.L6.TIME_ZONE_NOT_UTC judges which zone the server is on — an idiom question. This one judges whether the server can resolve a named zone at all, which is a misconfiguration.

One rule id carries one category. Folding a safety finding into an idiom one would put it in the wrong band for anyone gating on categories.

What is not reported

An offset value is resolved arithmetically and SYSTEM defers to the host clock — neither touches the tables, and neither is reported. That is the whole false-positive surface: the rule fires only where the dependency actually exists.

A server whose tables cannot be read is reported as undetermined, not as a finding. On a managed database the mysql schema is commonly out of reach, and "we could not look" is not "they are empty".

Sources