What format_version Actually Does
When Minecraft Bedrock loads a behavior pack or resource pack, it does not treat every JSON file the same way. As the game evolves, Mojang changes how components are structured, renames fields, and replaces old systems with new ones. To stop these updates from breaking older add-ons, the engine keeps multiple versions of its file parsers inside the game code. The format_version string at the top of your file selects which parser the game will use for that specific file.
If you declare an older format version, the engine reads your file using the rules that existed when that version was current. If you declare a newer format version, the engine expects the file to follow the updated schema and unlocks components introduced in that update. Because of this, you cannot mix and match syntax from different eras in the same file. A component written for a 1.16.100 item parser will fail to load or simply be ignored if the file header claims it is using the 1.20.50 schema.
This versioning applies per file, not per pack. Your behavior pack can contain an entity built on format version 1.16.0 alongside a block built on 1.20.60 and a recipe using 1.12.0. The engine evaluates each file independently during the pack loading phase.
Format Version vs. min_engine_version
New creators frequently confuse format_version with the min_engine_version array found in manifest.json. While both use version numbers that match Minecraft releases, they control completely different parts of the runtime environment.
The format_version lives inside individual asset and behavior files (such as entities, blocks, items, and render controllers). It strictly governs the syntax and schema of the single JSON file it is written in. By contrast, min_engine_version is set once in your pack manifest and tells the game the minimum base game behaviors your entire pack relies on, as well as preventing older versions of Minecraft from equipping a pack they cannot support.
A common rule of thumb is that your manifest's min_engine_version should be equal to or higher than the highest format_version used in most of your behavior files, though individual files can safely retain older format versions if they do not need new features.
{
"format_version": 2,
"header": {
"name": "Example Behavior Pack",
"description": "Demonstrates manifest format version versus min_engine_version.",
"uuid": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
"version": [1, 0, 0],
"min_engine_version": [1, 20, 80]
},
"modules": [
{
"type": "data",
"uuid": "f1e2d3c4-b5a6-4987-8654-3210fedcba98",
"version": [1, 0, 0]
}
]
}How Different Subsystems Use Versions
A major point of confusion is that format_version does not advance uniformly across every file type. Mojang only updates the parser version for a specific subsystem when that subsystem actually receives schema changes. If recipes have not changed their JSON structure since 1.12.0 or 1.16.0, then 1.12.0 remains a completely valid format version for a recipe, even when you are developing for Minecraft 1.21.0.
Additionally, some files use integer format versions rather than semantic version strings. The manifest.json file uses an integer (currently 2), whereas entities, blocks, items, and client files use three-part version strings like "1.20.80". Some resource pack files, such as animations and attachables, locked into specific milestone versions years ago and rarely require newer strings.
If you set a format_version on a file to the current game version when that specific subsystem has not been updated, the engine will usually fall back to the most recent parser it has for that file type. However, if you set a format_version higher than the version of Minecraft the player is currently running, the parser will reject the file outright.
| File Type | Pack | Common Stable Versions | Notes |
|---|---|---|---|
| manifest.json | BP / RP | 2 | Always an integer, never a string. |
| Entities | BP | "1.16.0" to "1.21.0" | Updates frequently as new AI goals and properties are added. |
| Client Entities | RP | "1.10.0" | Rarely changes; 1.10.0 remains the standard for entity definitions in RP. |
| Blocks | BP | "1.20.60", "1.21.0" | Older versions like 1.16.0 lack modern block traits and permutations. |
| Items | BP | "1.10", "1.20.50", "1.21.0" | 1.16.100 was formerly common but was superseded by the 1.20.50+ schema. |
| Recipes | BP | "1.12", "1.16", "1.20.10" | 1.20.10 added recipe unlocking requirements; 1.12 still works for basic crafting. |
| Geometry (Models) | RP | "1.12.0", "1.16.0" | 1.12.0 introduced the modern minecraft:geometry array structure. |
| Render Controllers | RP | "1.8.0", "1.10.0" | Almost all vanilla and custom render controllers use 1.8.0. |
| Animations & Controllers | RP / BP | "1.8.0", "1.10.0" | 1.10.0 is the standard for both resource and behavior animations. |
| Loot Tables & Trade Tables | BP | None | These files do not use a format_version field at all. |
Case Study: Item Schema Changes Across Versions
The clearest way to see format_version in action is by looking at behavior pack items. Over the lifespan of Bedrock Edition, custom items have gone through three major schema eras: the legacy 1.10 format, the experimental 1.16.100 format, and the modern 1.20.50+ format.
When Mojang stabilized custom item components in the 1.20.50 update, they changed several component names and structures. For example, setting an item's display name and icon changed syntax, and the way creative menu categories are assigned was moved out of the components list and into the description header.
If you try to use the modern "minecraft:max_stack_size" integer syntax or the "menu_category" description object inside a file marked as "1.10", the parser will fail. The file must declare "1.20.50" or newer to unlock the modern item parser.
{
"format_version": "1.20.50",
"minecraft:item": {
"description": {
"identifier": "wiki:custom_gem",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:icon": {
"textures": {
"default": "custom_gem_texture"
}
},
"minecraft:display_name": {
"value": "item.wiki:custom_gem.name"
},
"minecraft:max_stack_size": 64
}
}
}Case Study: Modern Block Definitions
Custom blocks experienced a similar evolution. Early data-driven blocks relied on experimental toggles and used components that have since been retired. In modern Bedrock (1.20.60 and later), block components use very explicit naming conventions.
For instance, mining speed and explosion resistance used to have shorter component names in early experimental schemas. Under a modern format_version like "1.20.80", you must use "minecraft:destructible_by_mining" and "minecraft:destructible_by_explosion". Similarly, referencing a custom model requires "minecraft:geometry" paired with "minecraft:material_instances".
If you copy a block snippet from an old tutorial that uses a 1.16.100 format version and simply change the number at the top to "1.20.80" without updating the component names inside the file, the game will throw Content Log errors for every outdated component.
{
"format_version": "1.20.80",
"minecraft:block": {
"description": {
"identifier": "wiki:reinforced_stone",
"menu_category": {
"category": "construction"
}
},
"components": {
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 5.0
},
"minecraft:destructible_by_explosion": {
"explosion_resistance": 30.0
},
"minecraft:geometry": "minecraft:geometry.full_block"
}
}
}Guidelines for Choosing and Upgrading Versions
When starting a new file, do not blindly type the current Minecraft release version into every format_version field. For resource pack files like render controllers (1.8.0), client entities (1.10.0), and geometries (1.12.0), stick to their established milestone versions. For behavior pack files like blocks, items, and entities, use the version string of the current stable release (or the specific release that introduced the components you need).
Avoid upgrading the format_version of existing, working files in your pack unless you specifically need to add a new component that requires a newer parser. Leaving an older entity on "1.16.0" is completely fine and is exactly how vanilla Minecraft handles many of its own built-in mobs. If you do bump the version number on an old file, always test it with the Content Log enabled to catch any components whose syntax changed between the two versions.
Which versions this applies to
Applies to all Minecraft Bedrock versions. Specific component availability depends on the version string chosen (e.g., 1.20.50+ for modern items, 1.20.60+ for modern blocks). No experimental toggles are required when using stable format versions.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Content Log error stating a file failed to parse because the format_version is newer than the current game version, or the asset silently fails to load. | You made a typo in the version string (for example, writing "1.210.0" instead of "1.21.0") or used a preview version number while testing in the stable release of the game. | Lower the format_version string to match or sit below the exact version of Minecraft Bedrock you are testing in. |
| Pack fails to appear in the game menu, or manifest error: "format_version is not a valid integer". | In manifest.json, you wrote the format_version in quotes as a semantic string like "1.20.0" or "2" instead of a raw JSON number. | Change the manifest.json format_version to the unquoted integer 2. |
| Content Log warning: "Unknown component" or "Failed to parse component" on a component you know exists in the game. | There is a mismatch between your file's format_version and the component syntax. Either the format_version is too old to recognize a newly added component, or the format_version is new and the component was renamed or removed in recent updates. | Check when the component was introduced. Either update the format_version to a modern release (such as "1.20.80") and rewrite outdated components to match the modern schema, or revert the component syntax to match your older format_version. |
| 3D block or entity model is invisible in-game and the Content Log reports a geometry parsing failure. | Your geometry file uses the legacy 1.8.0 structure (where geometry identifiers are top-level keys) while declaring "format_version": "1.12.0", or vice versa. | Ensure the JSON structure matches the version. Format version "1.12.0" and "1.16.0" require the "minecraft:geometry" array wrapper containing a "description" object and a "bones" array. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
