Skip to content

STLs In Git Repos

About 960 wordsAbout 3 min

SoftwareWebInfrastructure

2025-06-28

Lets get the TLDR right out of the way up front:

Warning

if you use any binary files in a git repo (like an STL) make sure you modify your repo's .gitattributes file (you may need to create it but many init scripts like Vue will do this automatically for common binaries)

.gitattributes
* text eol=lf
*.txt text eol=crlf

*.png binary
*.jpg binary
*.jpeg binary
*.ico binary
*.tff binary
*.woff binary
*.woff2 binary

*.stl binary
*.obj binary
*.3mf binary

Hours of Anguish

When I was developing this website I thought it would be pretty neat to embed STL files in webpages so I wrote a vue component to do just that. This worked completely fine when running locally on my machine, but did not work at all when deployed to Cloudflare's worker hosts.

First I assumed something was broken in my vue component so I did a bunch of optimization and added debugging with the loader which probably needed to happen anyways, but after a few hours of trying that I determined that the component was working fine, but something was wrong with the STLs.

Diagnosing STLs

Well eventually I tried downloading the STL directly from the public route that is used by the component to request the file from the host server. When I did that I found that the file was off by 14 bytes and there were 0 matching bytes between the source and the downloaded version. Weird. I tried opening the STL with Prusa Slicer and the file was corrupted enough that it failed immediately which meant the header had to be completely wrong.

(The Absence of) CloudFlare Corruption!

I thought "well obviously cloudflare is doing some annoying compression optimization that is screwing up my binaries" which was backed up by several 4 year old forum posts indicating others had problems with other types of binaries. So next I started messing with the _headers file. This file (documenation) can be used to insert custom header handling for CORS and content type and other such annoyances. After some digging and iterating I ended up with the following:

_headers
/*.stl
  Content-Type: application/octet-stream
  Content-Encoding: identity
  Cache-Control: public, max-age=31536000, no-transform

Essentially what this enforces is that there should be no transformation or compression of the binary content that ends with the extension .stl aka my precious 3d files. Whether or not this actually does anything within the CloudFlare CDN is not super clear. This did not fix the issue. Time to open a support ticket, but before I do...

It's Always The Last Thing

I went to the GitHub repo that hosts the source code of this website and downloaded the STLs straight from it. Would you look at that, corrupted. At this point any git vets reading this are likely screaming at their screen. I remembered back to a similar issue I had at work where files were getting corrupted in the repo. The short if it is that git does a bunch of stuff that starts from the assumption that all files are text files. The primary reason for this is the way End of Line(EOL) characters are interpreted. When git version controls files, it does all sorts of stuff to manage merging of files and what not that rely on the fact that a Carriage Return (CR) and Line Feed (LF) right after each other are interpreted as a new line. This is helpful for code, but if you have a binary file that does not care about newlines since it is a literal representation of a byte array things can go a bit haywire. This is all to say, you need to tell git that certain things are not text files. This is done through the .gitattributes file. A common misconception is that adding binary exceptions here disables version control for these files, this is not true. While git is not great at version control of binaries, it does work for the most part. I would personally not attempt a merge that includes a binary merge though. Because of gits history of difficulty with binaries, there are many options that fill this void in the game dev world like Plastic SCM which is the defacto SCM for Unity game projects (and was eventually bought and now run by Unity) as it handles 3D assets very well.

The Fix

Well enough talk, as mentioned at the top of this page, the fix for this very annoying problem was just adding the following to my .gitattributes file:

.gitattributes
*.stl binary
*.obj binary
*.3mf binary

The Vue/VuePress initialization script had already filled in binary exceptions for images and other common binary assets so the file was already there. You might need to create this file if you do not have one in the root level of your repo.

Addendum

You may not need to do this at all now. Git has improved binary detection substantially recently and if any NULL characters are detected within the first 8,000 characters of a file, git should assume the file is a binary but why risk it. Just make a .gitattributes file and be done with it.

This was a massive time sink for a very simple problem. A great lesson to start with the simple stuff and work your way up to "maybe a massive multi billion dollar mega corp specializing in web infrastructure is corrupting my files" as that is probably not the case.