Speaking of signature verification

One seemingly silly problem to deal with for those who host a “modded” Minecraft server is getting people to properly install those modifications. Copying a few files here and there seems simple enough, but it would be silly to say that connecting a backup generator to an electrical mains should be easy, just because it was easy to someone who dealt in the business. It comes down to an issue of numbers: if the difficulty was, for example, 10% harder, that could mean that there are 20% less people who can do it.

Several months ago, I updated my Minecraft launcher to support custom downloads and open sourced the entire launcher. While the update system worked pretty well, there was one caveat: it required that downloads be digitally signed, similar in principle to the browser verification of truly coming from Setting up digital signatures is pretty straightforward, but it’s a straightforward in the same vein as client installation – it is easy if you are familiar with the tasks involved. For that reason, as of today, I have decided to disable digital signature verification for custom packages, which should make it vastly easier (vanilla downloads from Mojang are unaffected). I was trying hard to avoid this, but other, more elegant options require a currently unrealistic input of time and effort from me.

tl;dr: I have made a change to my Minecraft launcher which vastly makes the use of the custom update feature easier to setup, which allows you to setup a custom modified MC client for people. Use it to make playing with friends less hectic, or use it to distribute necessary files for a modded server. After following the steps described within this post, you should be able to distribute your own files and install them into a user’s game. Towards the end of the post will be a discussion of some non-technical issues involved with this. Update to the latest version of the launcher to use this newest change.

Building the package


You’ll need three files:

  1. A .zip file containing the files to install. This archive should contain files that would be placed into the root Minecraft folder (aka. .minecraft).
  2. A package XML file containing a list of files to install, with a link to the ZIP archive.
  3. An update XML file containing a link to the package file and a version string.

The package XML file is the more complicated file, as it has to contain all the files that need to be installed even on a fresh installation of Minecraft. You’ll see in the example file below three <filegroup> sections, the first of which is your main concern, as it points to the ZIP archive mentioned above. The other file group sections merely point the launcher to where additional required Minecraft files can be acquired. As you may notice, you would have to change the directory URL for the ZIP file, the filename of the ZIP file, as well as the size in bytes so that the launcher can accurately draw the download progress bar.

The latter update XML file is considerably simple. The version string you choose can be anything, but it must stay the same until you issue an update. Upon the launcher finding a different version, it will download the referenced URL to update. The URL points to the current latest package version.

Once you’ve placed all three files on a web server somewhere, fire up the launcher, create a new configuration, choose a folder to store the files, and insert the URL to the update XML file.

Installation mechanisms

The next question arises is that of “how does the launcher actually install the file?” It simply extracts the files over the Minecraft directory and overwrites any files. As for updates, the launcher keeps track of the list of files from prior updates and removes any files that disappeared between updates. A player’s saves would not be removed because it would not be part of the download ZIP, but any configuration change made by the user on a file added by the update would be wiped on next update. Overall, this process allows for very simple installation at the cost of some flexibility.


Support for incremental updates is there, as the resources downloaded from Mojang use that, but it is a bit convoluted and meant to fit in with Mojang’s existing download scheme. I may detail how it works in a future post, but for now, sticking to full updates is easier to get working.

The other issues

What about minecraft.jar? You have bundle that with the .zip (to keep it simple for you), which is not entirely kosher, but remember that you can already download Minecraft (without logging in) from However, this decision is up to you.

The second issue is that you may distribute other people’s work, which will inevitably happen, and so I can only ask of you to be sure that to have permission to distribute the files. The terms are often mentioned on people’s posts, but send them a friendly message if they are not clear about it.

There are currently a few rough edges with the launcher. The fact that you have to fiddle with the configuration screen is not ideal, and the fact that you can’t just two click add a configuration is another dislike from me. Letting users add their own client customization is also not so easy, although it could argued that you would not want to make that easy. If you distribute your own copy of the launcher (and make appropriate modifications), these rough edges disappear, but this is obviously not the best option. I will see if I can find some time to sand out some of the left over difficulties. Remember that you can contribute to the project, as it is open source.

  • bendem

    Is there a doc which explain with more details updates likes “incremental” ones ?

    And does “deletes files not found in the new .zip” mean that worlds which are not in the .zip are deleted ?

    Thanks for your work, you’re awesome ;-)

    • sk89q

      It seems Disqus login is having problems.

      The Minecraft files are downloaded only if they are changed, but unfortunately I admit that I don’t entirely remember how the mechanics of incremental updates work, or how well they work for .zip files.

      I meant that if you put a file in the first .zip, and that file is not in the next update .zip, that file will be wiped, but since the world is not in the first .zip to begin with, it would not be wiped. Unless, of course, you put a world in the .zip.

      • bendem

        The update take point of the current zip and the previous ? and make a diff of them to know what to update and what to delete ?

        • sk89q

          Yes, that’s correct. It doesn’t have the original .zip on hand but it has a list of paths.

          • bendem

            Ok, thanks ;)

  • QuestionMark

    Is it possible to create two or more separate updates? I have a ZIP file containing mods and another zip containing texture packs. I dont want the users to download the 200MB texture pack ZIP every time i add, remove or update a mod. The ZIP with the mods is just a few KB.

    • sk89q

      This should work I believe: Add verify=”md5″ to a new , and on the server, make sure the Etag (sent as a HTTP header) is the MD5 hash of the file. The launcher should not re-download the texture pack (or delete it during an update).

      • QuestiomMark

        Thank you! Not sure how to do that, but at least I know what to type into Google. I assume I will have to configure the web server to generate etags? Im running lighttpd.

        • sk89q

          Hmm, ETags are standard fare, but I don’t think you can (easily) make Lightttpd issue MD5 ETags (they would be more computationally intensive). ETags don’t normally need to be a hash of the file because they are merely used so that a web client can detect a change and not re-download the file, but Mojang also abuses it to send a hash of the file, and I think the launcher only supports this mode of functioning.

          I will see if I can have it support regular non-hash ETags, which would make it much easier for you.

          • QuestionMark

            I have enabled Etags in lighttpd.conf and made a new filegroup as you described. It seems Lighttpd actually sends a MD5 hash, but i might be mistaken. Trying to download the update i get this error:
            Signature for did not match; expected 1863862083, got cbb97d6666c95a0509c2f196b9a037e8
            When i run “md5sum” on the server the md5sum matches, cbb97*.

          • sk89q

            …I suspect I swapped those variables in the error message. It probably got the numeric numbers, and expected the hash.

  • Randall

    I keep getting a the update server us unreachable (.org.xml.SAXParseException; LineNumber:1; columnNumber 55; White spaces are required between publicid and systemid

    I checked all the files and config files. every things seems in order, any ideas? and thank you for making great minecraft mods

    • sk89q

      Send me a pastebin of the files. There might be a syntax error that your eyes are glossing over.

      • Randall

        I am pretty sure I am glossing over something. always good to have some fresh eyes to look at it. Thank you again for your help

        • Randall

          PLease delete the dups. I am sorry It didn’t show up on browser for some reason, I am sorry fot that.

        • sk89q

          OK, so there’s nothing wrong with your eyes and I am perplexed. I’ll have to try loading it into the launcher later so I can reproduce it.

          • Randall

            I am using the latest build you have on jenkins as well if that helps.

        • sk89q

          Apparently I was told that your problem may be that you did not specify the exact URL to the .xml file in the configuration window, possibly putting the link to a directory containing the .xml or something.

          • Randall

            Thank you sk89q, you are very helpful and thank you so much for your help. You are right I had to put in for example now it is working fine. I hope this helps anyone with the same issue. Thanks again

      • Randall

        sk89q thank you again. I think it is something i glossed over. thank you again here is the pastebin.

    • Randall

      sk89q thank you again for your help. It could be something did. here is the pastebin you asked for.