Takeout JSON

supplemental-metadata.json in Google Takeout, Explained

Why Google renamed the Takeout sidecars in 2024, why some names are cut short, how the (1) duplicates pair up, and why old scripts miss them.

You ran a script that used to fix Takeout exports fine, and this time it skipped half the photos. Or you looked in the folder and saw IMG_5512.HEIC.supplemental-metadata.json next to one photo and PXL_20240311_183022711.jpg.supplemental-m.json next to another, and wondered whether the second one is broken.

Neither is broken. Google changed how it names the sidecars, and most guides written before 2024 do not know.

The 2024 rename

For years the sidecar for IMG_5512.HEIC was IMG_5512.HEIC.json. Photo name, then .json. Simple, and every script matched on it.

Sometime in 2024 Google switched to IMG_5512.HEIC.supplemental-metadata.json. Same contents, same fields, longer name. The idea seems to be that supplemental-metadata describes what the file is, rather than leaving a bare .json that looks like it might be the photo's own data. Exports made since then use the new name. If you have an old export on a drive somewhere, it uses the old one, and a mixed folder can contain both.

Anything that looks for <photo>.json now finds nothing and moves on. Some tools report "no sidecar found" for every file. Others fall back silently to the file date, which is the download date, so the photos come out wrong with no error. That silent failure is the source of many "the fix did not work" posts.

The 46-character cut

The second change is older but the rename made it bite more. Google truncates the whole sidecar filename to 46 characters. With the old short suffix that rarely mattered. With .supplemental-metadata.json added, any photo name over about 19 characters loses part of its suffix.

A Pixel photo named PXL_20240311_183022711.jpg is 26 characters. Add .supplemental-metadata.json and you get 53. Google cuts it to 46: PXL_20240311_183022711.jpg.supplemental-m.json. A Samsung 20240311_183022.jpg gets 20240311_183022.jpg.supplemental-metada.json. Every camera brand produces a slightly different truncation, so there is no single suffix to match.

The reliable rule is: the sidecar name is a prefix of <photo name>.supplemental-metadata.json. A script has to check that, not compare a fixed string. Long original filenames, such as ones you typed yourself, can be cut into the photo name itself, which is why the title field inside the sidecar is worth reading.

Where the (1) goes

Google Photos allows two files with the same name, and Takeout has to put them in one folder. It adds a counter to the second: IMG_5512.HEIC and IMG_5512(1).HEIC.

You would expect the sidecars to be IMG_5512.HEIC.supplemental-metadata.json and IMG_5512(1).HEIC.supplemental-metadata.json. They are not. The counter moves to the end of the sidecar name, before .json: IMG_5512.HEIC.supplemental-metadata(1).json. With the old style it was IMG_5512.HEIC(1).json.

So a tool must take the photo name, remove the (1), build the sidecar name, and put the (1) back just before .json. Combine that with truncation and you get names like PXL_20240311_183022711.jpg.supplemental-(1).json. Real exports contain these.

Duplicates with counters are more common than you would think. The same photo saved to two albums, a photo you edited and Google kept both versions of, or two phones that both named a file IMG_0001.JPG all produce them.

The edited copies

Photos edited inside Google Photos come out as two files: IMG_5512.HEIC and IMG_5512-edited.HEIC. There is usually one sidecar, attached to the original name. The edited copy has no sidecar of its own, so a naive tool leaves it undated. A careful tool strips -edited and reuses the original's sidecar. More on this in Takeout duplicates and edited versions.

Matching by hand

If you are using exiftool, run it twice, once for each suffix:

exiftool -r -d %s -tagsfromfile "%d/%F.supplemental-metadata.json" "-DateTimeOriginal<PhotoTakenTimeTimestamp" -ext jpg -ext heic -overwrite_original .
exiftool -r -d %s -tagsfromfile "%d/%F.json" "-DateTimeOriginal<PhotoTakenTimeTimestamp" -ext jpg -ext heic -overwrite_original .

Then list what is still undated with exiftool -r -if 'not $DateTimeOriginal' -filename .. What remains is the truncated and (1) set. The simplest fix is to rename those sidecars to the full expected name with a short script before running exiftool again. GooglePhotosTakeoutHelper, a free community tool, has this matching built in and is the usual recommendation if you are happy in a terminal. Its releases sometimes lag behind Google's changes, so check the issue tracker if a run skips files.

The app

Takeout JSON Metadata Fixer handles all of these cases without configuration, on macOS, Windows and Linux.

For each photo it tries the 2024 name, the old name, the moved (1) counter, and finally any .json in the folder whose name is a prefix of the full expected name. Edited copies borrow the original's sidecar. Then it writes the date and GPS into the file. It reports how many photos matched a sidecar and how many fell back to EXIF or the file date, so you can see whether the pairing worked before you delete anything. A dry run shows the plan without writing. The first 500 photos are free.

Frequently asked questions

Do the contents of supplemental-metadata.json differ from the old .json?

No. The fields are the same: title, photoTakenTime, creationTime, geoData, geoDataExif and so on. Only the filename changed.

My photo has no sidecar at all. Why?

Live Photo clips often have none. Some very old uploads have none. And if a sidecar is truncated or has a moved counter, your tool may be reporting it as missing when it is there. Look in the folder yourself.

Can I rename the sidecars back to the old style?

Yes, and it makes old scripts work again. A rename that strips .supplemental-metadata and moves (1) back onto the photo part of the name is enough. Do it on a copy first.

Will Google change the name again?

Possibly. The safe approach for any tool is to match by prefix and by the title field, not by an exact suffix.