Skip to content
>GLB_
Go back

Why Athena Returns No Rows on Partitioned Tables (and How to Fix It)

The files are in S3. The table exists in the Glue Data Catalog. SELECT COUNT(*) returns 0. No error, no warning.

This is almost always a partition metadata problem. Athena doesn’t list S3 to find your data. It asks the catalog (or partition projection) which partitions exist, and only reads those prefixes. If the catalog and S3 disagree, Athena trusts the catalog.

This post covers the causes I’ve hit in practice, in the order I check them.

Step 0: confirm it’s a partition problem

Before touching anything, confirm what Athena thinks exists:

SHOW PARTITIONS my_db.events;

And compare against what’s actually in S3:

$ aws s3 ls s3://my-bucket/events/ --recursive | head

If SHOW PARTITIONS is empty or missing recent values, you have a metadata desync. If partitions exist but queries still return nothing, jump to causes 4–6.

Cause 1: new partitions were never registered

Writing files to s3://my-bucket/events/dt=2026-10-01/ does not register partition dt=2026-10-01. Something has to add it to the catalog.

Fix for Hive-style layouts (key=value paths):

MSCK REPAIR TABLE my_db.events;

Two caveats:

For targeted additions, prefer explicit DDL:

ALTER TABLE my_db.events ADD IF NOT EXISTS
  PARTITION (dt = '2026-10-01') LOCATION 's3://my-bucket/events/dt=2026-10-01/';

Cause 2: your layout isn’t Hive-style

MSCK REPAIR TABLE only understands key=value prefixes. If your writer produces:

s3://my-bucket/events/2026/10/01/part-0000.parquet

MSCK silently does nothing. Options:

Cause 3: camelCase partition keys

Athena lowercases column and partition names. A path like eventDate=2026-10-01/ won’t match a partition column the catalog stores as eventdate, and MSCK won’t pick it up. Use lowercase (snake_case) partition keys in your S3 paths.

Cause 4: partition projection is enabled (and misconfigured)

This one is non-obvious. When partition projection is enabled on a table, Athena ignores partition metadata registered in the Glue Data Catalog for that table. Running MSCK REPAIR TABLE or a crawler won’t help, because Athena isn’t reading those partitions anyway.

Check the table properties:

SHOW TBLPROPERTIES my_db.events;

Typical failure modes:

A working example for a non-Hive daily layout:

ALTER TABLE my_db.events SET TBLPROPERTIES (
  'projection.enabled'          = 'true',
  'projection.dt.type'          = 'date',
  'projection.dt.format'        = 'yyyy/MM/dd',
  'projection.dt.range'         = '2024/01/01,NOW',
  'projection.dt.interval'      = '1',
  'projection.dt.interval.unit' = 'DAYS',
  'storage.location.template'   = 's3://my-bucket/events/${dt}/'
);

Cause 5: the files are “hidden”

Athena ignores objects whose names start with _ or .. Some writers produce _SUCCESS, _temporary/ and similar markers. That’s expected. The problem is when your actual data files get those prefixes, which happens with some custom writers or failed renames.

Check which files Athena is reading:

SELECT "$path", COUNT(*) FROM my_db.events
WHERE dt = '2026-10-01'
GROUP BY 1;

If no $path rows come back for a partition you know has files, look at the object names.

Cause 6: the crawler rewrote the schema

If a Glue crawler runs on the table, it can re-infer partition keys from a slightly different path structure (an extra prefix level, a stray file at the root) and change the partition columns. Your WHERE dt = ... now filters on a column that no longer maps to the path.

Compare SHOW CREATE TABLE before and after crawler runs. For tables you own end-to-end, I’d rather manage partitions with DDL or projection and keep the crawler away from them.

Which fix to pick

SituationApproach
Hive-style paths, few partitionsMSCK REPAIR TABLE after loads
Many partitions, predictable values (dates, IDs)Partition projection
Non-Hive paths, irregular valuesALTER TABLE ADD PARTITION from the writer
Partitions written by a Glue jobenableUpdateCatalog on the sink

For high-volume, date-partitioned tables, projection removes the problem entirely: no catalog calls, no repair step.

References


Share this post:

Related Posts


Previous Post
Where Agents Schema fits in a dbt → Snowflake → Looker pipeline
Next Post
Tuva's encounter grouper only groups claims. Here's what happens to your ADT encounters