The rule every reported example fits
Google has not documented the naming, but the examples collected in the immich-go test suite and in the GooglePhotosTakeoutHelper issue tracker all follow one pattern. Take the file's original name, add .supplemental-metadata, and if the result plus .json would be longer than 51 characters, keep only the first 46 characters before adding .json. A name that is short enough keeps the whole suffix. A name that is long enough loses all of it and ends up as the first 46 characters of the file name itself plus .json.
The count is in UTF-16 code units, which matters for emoji and some non-Latin scripts. In the immich-go tests one JSON name with emoji is 51 units long but only 29 visible characters. JavaScript's String.length counts the same units, and FixMyTakeout counts that way too.
Measured examples
Each cut name below is exactly 51 characters. The first row shows a name short enough to keep the full suffix.
| File | Its JSON | Reported in |
|---|---|---|
20161105_170829.jpg | 20161105_170829.jpg.supplemental-metadata.json (46, nothing cut) | immich-go issue #652 |
MVIMG_20191230_232926.jpg | MVIMG_20191230_232926.jpg.supplemental-metadat.json | Collected from the immich-go tests and the GPTH #353 and #449 threads |
PXL_20240817_202602411.mp4 | PXL_20240817_202602411.mp4.supplemental-metada.json | GPTH issue #353 |
MVIMG_20200207_134534~2.jpg | MVIMG_20200207_134534~2.jpg.supplemental-metad.json | Collected from the immich-go tests and the GPTH #353 and #449 threads |
Screenshot_20200301-161151.png | Screenshot_20200301-161151.png.supplemental-me.json | Collected from the immich-go tests and the GPTH #353 and #449 threads |
Screenshot_20231027_123303_Facebook.jpg | Screenshot_20231027_123303_Facebook.jpg.supple.json | immich-go test suite |
0bf4bdc0-0194-43e1-a85b-8823858343c7.jpg | 0bf4bdc0-0194-43e1-a85b-8823858343c7.jpg.suppl.json | GPTH_Neo issue #123 |
Screenshot_2024-08-31-00-53-48-647_com.snapchat.jpg | Screenshot_2024-08-31-00-53-48-647_com.snapcha.json | immich-go test suite |
PXL_20230809_203449253.LONG_EXPOSURE-02.ORIGINA.jpg | PXL_20230809_203449253.LONG_EXPOSURE-02.ORIGIN.json | immich-go test suite |
The last two rows show the older cut that existed before the suffix did: the media name itself is capped at 51 characters with its extension kept, and its JSON is the first 46 characters plus .json, so the JSON name does not even contain .jpg. A comment on GPTH pull request #449 describes the same outcome for new exports once the suffix has been consumed entirely.
Examples from immich-go matcher_test.go, immich-go #652, GPTH #353 and GPTH_Neo #123.
Why tools written before October 2024 lose the dates
The original GooglePhotosTakeoutHelper looks for name.jpg.json. Issue #353, "supplemental-metadata not supported", was opened on 27 October 2024 and is still open; the last commit to that project is from 29 January 2025, and the two pull requests that add the suffix (#375 and #449) were never merged. When it finds no JSON it falls back to guessing a date from the file name, and the reporter of #353 ended up with photos dated in 1868 and 2068.
immich-go had the same gap until early 2025. Issues #652, #673, #674 and #698, all filed between 25 January and 10 February 2025, cover the suffix, the truncated forms, edited files and JSON names missing the extension, and all were fixed by 15 February 2025. Its matcher now accepts any prefix of supplemental-metadata as the segment between the last two dots, even a single letter. GooglePhotosTakeoutHelper_Neo, the maintained fork, generates the candidate names under the 51 cap and tries the supplemental form before the plain one.
If an importer or script you used was last updated before late 2024, it most likely did not see the JSON files and dated your photos some other way, most often by the file's modified time or a guess from the name.
How FixMyTakeout matches them
For each photo or video FixMyTakeout builds the names Google would have written, in this order, and looks each one up in the same folder (merged across every zip part):
name.ext.supplemental-metadata.json, cut to 46 characters plus.jsonwhen longer than 51.name.ext.json, the classic form, with the same cut.- Any JSON in the folder whose name is
name.ext.followed by a shortened form ofsupplemental-metadata:.supplemental-metad,.supple,.suppl,.s. This catches exports where the cut fell at a different position than the rule predicts.
Lookups are tried with the exact name first and then case-insensitively, so IMG_0001.jpg still finds IMG_0001.JPG.supplemental-metadata.json. The report column matched_by tells you which rule fired: supplemental-metadata name, classic name or shortened supplemental-metadata name.
Check your export for the cut
- Sort a
Photos fromfolder by name and find a screenshot: their names are the longest. If its JSON ends in something like.supple.json, your export has the cut. - Run the export through FixMyTakeout and open
fixmytakeout-report.csv. Filtermatched_byforshortened supplemental-metadata nameto see every file that needed the third rule. - Rows with an empty
sidecarcolumn had no JSON under any rule; thedate_sourcecolumn shows what was used instead.