Skip to content

Minecraft Bedrock Add-Ons: Behaviour Packs, Resource Packs and manifest.json

How Bedrock add-ons work: behaviour packs vs resource packs, where they go on the server, manifest.json UUIDs, and the world files that switch a pack on.

Updated August 19, 2026
Minecraft

Bedrock Edition has no datapacks, no plugins and no mods. What it has instead are add-ons, and an add-on is one or both of two things: a behaviour pack, which changes what the game does, and a resource pack, which changes what the game looks and sounds like. Neither has any relationship to a Java Edition datapack. You cannot install one on the other, in either direction, and the reason is not a missing loader — it is that the two editions read entirely different files.

This guide covers what the two pack types actually contain, where they live on a Bedrock Dedicated Server, what is inside manifest.json, the dependency link that ties a behaviour pack to its resource pack, and the two small JSON files in the world folder that decide whether any of it loads at all. For first boot and general operation see Setting up your Bedrock Minecraft server; for every configuration key mentioned here see Bedrock server.properties: The Complete Key Reference. The Java Edition equivalent — datapacks and URL-served resource packs — is a different document: How to Install Datapacks and Resource Packs.

Verified against Bedrock Dedicated Server 1.26.44.3

Folder names, manifest fields, error strings and console messages below were read out of the official BDS 1.26.44.3 archive on 19 August 2026 — its bedrock_server_how_to.html manual, the manifest.json files of the vanilla and chemistry packs it ships, the en_US.lang message catalogue inside resource_packs/vanilla/texts/, and the server binary's own string table. 1.26.44.3 is the build Mojang's download API was serving on that date. Manifest field definitions are from Microsoft's creator documentation, which is the reference for pack structure.

Behaviour Pack or Resource Pack?

The split is clean, and it is the first thing to get right because it decides which folder a file goes in.

Behaviour pack Resource pack
Changes Entity behaviour, loot, recipes, trades, spawn rules, items, blocks, functions, scripts Textures, models, sounds, animations, fonts, UI, language strings
Runs on The server The client
Module type in the manifest data (or script) resources
Server folder behavior_packs/ resource_packs/
Players must download it No Yes
Distributed as .mcpack, or .mcaddon for a bundle .mcpack, or .mcaddon for a bundle

Mojang spells the folder behavior_packs, American-style, and that spelling is not optional — the server looks for that exact directory name.

Inside a behaviour pack the content folders are plural: the vanilla behaviour pack shipped in BDS 1.26.44.3 contains entities/, items/, loot_tables/, recipes/, spawn_rules/, structures/, trading/, biomes/ and cameras/. A resource pack carries the client-side half — textures/, models/, sounds/, entity/, render_controllers/, attachables/, texts/. The only file genuinely required in either is manifest.json.

.mcaddon and .mcpack are ZIP files with a different extension

The game names them "Minecraft Add-On" and "Minecraft Pack" internally, and the server's own error catalogue proves the format: a pack that will not open reports "Not a valid zip archive." An .mcpack is one pack; an .mcaddon is a bundle, normally a behaviour pack and its matching resource pack together. On a server you extract them and upload the folders, because BDS reads pack directories, not archives.

Where Packs Live on the Server

There are three places a pack can sit, and they differ only in which worlds can see it.

Folder Created automatically Scope
behavior_packs/ and resource_packs/ in the server root Yes, on first start Available to any world on the server
worlds/<level-name>/behavior_packs/ and .../resource_packs/ No Available to that world only
system_behavior_packs/ and system_resource_packs/ No — create them yourself Applied globally across all worlds

Microsoft's dedicated-server documentation is direct about the choice: unless a pack only makes sense in one specific world, put it in the shared folders at the top level.

The system_* folders are a different mechanism again. Mojang's manual describes them as holding "system administrator" packs applied across all worlds, and warns that a pack placed there has its pack and module UUIDs protected — any user pack reusing one of those IDs fails to load, with "Pack '%s' is using an ID which is protected by another protected pack."

Uploading a pack does nothing on its own

Putting files in behavior_packs/ makes a pack available. It does not switch it on. Mojang's shipped manual still says of those folders that "at the moment there's no way of activating them in a level", and taken literally that is true — BDS has no console command for it. Activation happens in the world folder, in the two JSON files described below. This is far and away the most common reason a correctly built add-on appears to be ignored.

Inside manifest.json

Every pack has one, at the top level of the pack folder, and it is the file Minecraft reads to decide whether the pack exists at all. This is the entire manifest of the vanilla behaviour pack that ships inside BDS 1.26.44.3:

{
    "format_version": 2,
    "header": {
        "description": "resourcePack.vanilla_server.description",
        "name": "resourcePack.vanilla_server.name",
        "uuid": "fe9f8597-5454-481a-8730-8d070a8e2e58",
        "version": [0, 0, 1],
        "min_engine_version": [ 1, 13, 0 ]
    },
    "modules": [
        {
            "description": "resourcePack.vanilla_server.description",
            "type": "data",
            "uuid": "79fccc3b-7bad-4f4f-aa97-d98108e6aa33",
            "version": [0, 0, 1]
        }
    ],
    "dependencies": [
      {
        "uuid": "0575c61f-a5da-4b7f-9961-ffda2908861e",
        "version": [0, 0, 1]
      }
    ]
}
behavior_packs/vanilla/manifest.json

One version marker and five sections are possible, of which only the first three are common:

Section Purpose
format_version The manifest syntax version. 1 for skin packs, 2 for resource, behaviour and world-template packs. A version 3 with SemVer strings is in preview
header Public-facing information about the pack: name, description, UUID, version, minimum engine version
modules What kind of content the pack brings in. One module per content type
dependencies Other packs, or built-in scripting modules, this pack needs
capabilities Optional engine features the pack switches on — chemistry, editorExtension, experimental_custom_ui, raytraced, pbr
metadata Authors, licence, and the tool that generated the file

The fields that matter operationally:

  • uuid — a standard xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx hexadecimal identifier. The header UUID identifies the pack; each module needs its own, different UUID. Two packs sharing one is a hard failure: "Provided UUID '%s' element already exists in pack manifest."
  • version[major, minor, revision]. It is how the game decides whether an imported pack replaces an existing copy: higher replaces, same or lower is ignored.
  • min_engine_version — the lowest game version the pack was written for, required for both pack types. Microsoft's guidance is to use the highest version available when you build the pack.
  • type on a module — resources, data, script, or world_template.

Version numbers are arrays on Bedrock, not integers

Java's pack.mcmeta carries a single pack_format number (now min_format and max_format). Bedrock's manifest.json carries [major, minor, revision] arrays and a min_engine_version. A malformed value is caught and named: "Provided '%s' element is not SemVer (semver.org) compliant in pack manifest." Do not copy a number from a Java guide into a Bedrock manifest — there is no field it fits.

A behaviour pack that adds a new mob needs textures and a model for it, and those live in a resource pack. The two are joined by a dependencies entry that names the other pack's header UUID and version, exactly as that pack declares them.

The vanilla behaviour pack above does this: its dependency UUID 0575c61f-a5da-4b7f-9961-ffda2908861e is the header UUID of resource_packs/vanilla. The chemistry packs shipped in the same archive do it in both directions — the behaviour pack depends on the resource pack and the resource pack depends on the behaviour pack — and both also declare "capabilities": ["chemistry"].

  "dependencies": [
    {
      // Chemistry resource pack
      "uuid": "0fba4063-dba1-4281-9b89-ff9390653530",
      "version": [1, 0, 0]
    }
  ],
  "capabilities": [
    "chemistry"
  ]
behavior_packs/chemistry/manifest.json (excerpt)

With the link in place, applying the behaviour pack pulls the resource pack in with it and players are told the pack is mandatory rather than optional — "This pack is a required dependency of another pack that is currently applied." Without it, the pack loads and the mob is invisible or untextured, and the server logs "Missing dependency with ID '%s' and version '%s'."

Scripting modules use the same section for a different job, listing module_name rather than uuid to name a built-in API:

    "modules": [
        {
            "type": "script",
            "uuid": "68c18ba2-cba3-4aae-9af4-fcae6b733325",
            "version": [0, 0, 1],
            "language": "javascript",
            "entry": "scripts/Main.js"
        }
    ],
    "dependencies": [
        { "module_name": "@minecraft/server", "version": "beta" }
    ]
manifest.json (a scripting behaviour pack)

Which modules a script may import is controlled server-side in config/default/permissions.json, which BDS creates on first run with an allowed_modules array. Only one script module is allowed per pack — extras are skipped with "Plugin [{}] - skipped, only one script module allowed per pack." The watchdog that stops a runaway add-on taking the server down is configured in server.properties; see the key reference.

Activating a Pack: the Two World Files

This is the step that is missing from most guides. Two JSON files in the world folder decide which packs are active:

  • worlds/<level-name>/world_behavior_packs.json
  • worlds/<level-name>/world_resource_packs.json

Both files are a flat JSON array. Each entry names a pack by the UUID from its manifest header and the version it expects:

[
  {
    "pack_id": "12345678-1234-1234-1234-123456789abc",
    "version": [1, 0, 0]
  }
]
worlds/Bedrock level/world_behavior_packs.json

pack_id is the pack's header.uuid — not a module UUID, and not the folder name. version is the three-integer array from the manifest. An optional priority integer sets load order, lower first.

You will often see world_behavior_pack_history.json and world_resource_pack_history.json beside them, recording every pack ever enabled for the world. The game writes those; leave them alone. All four filenames appear verbatim in the BDS binary, so the server genuinely reads them.

The whole procedure on a server:

  1. Extract the .mcpack or .mcaddon and upload the pack folder to behavior_packs/ or resource_packs/ — through the File Manager for something small, over SFTP for a large textured pack.

  2. Open the pack's manifest.json and copy the header uuid and version.

  3. Add an entry with that pack_id and version to worlds/<level-name>/world_behavior_packs.json, or the resource equivalent. If the file does not exist, create it; an empty one is [].

  4. Restart the server. There is no console command to reload the pack list.

A wrong UUID or version is skipped silently from the player's point of view

If the entry does not match an installed pack, the server drops it and carries on with the message "Configured pack (id: {}, version: {}) was not found and was ignored." The world loads, nobody is disconnected, and the add-on simply is not there. Turn on content-log-file-enabled and content-log-console-output-enabled in server.properties before you go hunting — that log is where every pack error is written.

Load Order and Pack Stacking

When two packs define the same thing, the one applied later wins. Microsoft calls this pack stacking, and it is why entry order matters: a second pack shipping its own dirt.png replaces the first one's, and the server warns about the item case explicitly — "Item '{}' has already been overridden by a pack higher in the pack stack!"

The server logs its resolved stack on load, one line per pack, as Pack Stack - [nn] <name> (id: <uuid>, version: <version>) @ <path>, or Pack Stack - None. The /packstack command prints the same thing to chat and is available to every player, not just operators.

BDS does ship a /reload command — the class and both of its description strings are present in the 1.26.44.3 binary. Plain /reload is "Reloads all function and script files from all behavior packs", which is genuinely useful while iterating on functions and scripts. /reload all is described as optionally reloading the world and all resource and behaviour packs too, but the server also carries the message "Only host player can reload the world", so do not build a workflow around it from a dedicated-server console. Either way it is not a configuration reload: nothing in server.properties is re-read, and adding a pack to world_behavior_packs.json still needs a restart.

Forcing Packs on Clients

A behaviour pack is server-side and applies to everyone automatically — there is nothing for the client to accept. A resource pack is different, because the client has to download it, and by default it is offered rather than imposed. One server.properties key changes that:

texturepack-required=true
server.properties

The shipped file's own comment reads "Force clients to use texture packs in the current world". With it on, joining players see "The owner of this world requires players to download all Resource Packs applied to it. Would you like to download them and join?", and declining means not joining. Packs that are a declared dependency of an applied behaviour pack are already mandatory without this key; texturepack-required extends the same treatment to every pack on the world, cosmetic ones included.

There is no resource-pack URL key on Bedrock

Java serves a resource pack from a URL with a SHA-1 hash, using the resource-pack, resource-pack-sha1 and require-resource-pack keys. Bedrock has none of those. The pack is stored in or beside the world and sent to the client by the server itself, and texturepack-required is the only related setting. If a guide tells you to paste a pack URL into server.properties, it is a Java guide — see How to Install Datapacks and Resource Packs for that workflow.

Pack Optimization

Newer BDS builds can pre-process packs into archives so clients spend less time loading loose files. Mojang ships its own packs this way already: behavior_packs/vanilla in 1.26.44.3 contains a __brarchive/ directory full of .brarchive files — entities.brarchive alone is 445 KB — alongside the loose JSON.

You can run the same process over your own packs by starting the binary with a config path instead of running it normally:

./bedrock_server.exe PackOptimizerConfigPath=D:/work/pack_optimizer_config.json
text
{
  "input_directory": "D:/work/packs_input",
  "output_directory": "D:/work/packs_output",
  "verbose_logging": false
}
pack_optimizer_config.json

Each subdirectory of input_directory is treated as one pack; the server optimises, writes the results and exits rather than running as a server. Two constraints: Microsoft documents the argument for Windows builds, and optimised packs raise the minimum client version to 1.26.40, so older clients fail to load them. They stay forward-compatible with later releases.

Why a Java Datapack Will Never Work on Bedrock

This is the question the whole page exists to answer, and the answer is not "Bedrock is missing a mod loader". It is that a datapack and a behaviour pack have essentially nothing in common except being folders of JSON.

Java datapack Bedrock behaviour pack
Root file pack.mcmeta manifest.json
Identity None — identified by folder name A UUID in the header, plus a separate UUID per module
Version declaration min_format / max_format integers version and min_engine_version integer arrays
Lives in <world>/datapacks/ behavior_packs/, or the world's own behavior_packs/
Switched on by /datapack enable, stored in level.dat An entry in world_behavior_packs.json
Content folders Singular since 1.21: recipe, loot_table, function, advancement Plural: recipes, loot_tables, functions, spawn_rules
Namespacing data/<namespace>/… Namespaced inside each JSON file's identifier
Scripting None — .mcfunction only .mcfunction plus a JavaScript API
Read by The Java server jar The Bedrock C++ engine

Drop a datapack into a Bedrock server's behavior_packs/ and the server finds no manifest.json and rejects it outright — "Unable to find manifest in pack." Drop a behaviour pack into a Java server's datapacks/ and the server finds no pack.mcmeta and reports Failed to read pack ... metadata. Neither is a fixable configuration problem, and neither is a licensing or loader gap: the two editions are separate programs that happen to share a name.

The same is true of the client half: a Java resource pack and a Bedrock resource pack are both ZIPs of textures, and neither loads in the other edition — different manifest file, different folder layout, different model format.

The one thing that does cross the boundary is the world itself, and only through a conversion tool. That belongs to Bedrock World Management.

When a Pack Does Not Load

Bedrock's pack loader names its failures. These are the messages it ships, and each one points at a specific mistake:

Message What it means
Unable to find manifest in pack. No manifest.json at the top level. Usually an extra wrapper folder from unzipping
Not a valid zip archive. The pack is a corrupt or partial archive
Unable to parse pack manifest with stack: %s Broken JSON — a trailing comma, or a smart quote from a word processor
Missing '%s' element in pack manifest. A required field is absent, most often min_engine_version
Provided '%s' element is not a valid UUID in pack manifest. A malformed or hand-typed UUID
Provided UUID '%s' element already exists in pack manifest. Two packs, or a pack and its module, sharing a UUID
Missing dependency with ID '%s' and version '%s'. The paired pack is not installed, or its version does not match
Folder structure in pack is too deep. The pack was nested inside extra directories on upload
The property '%s' has a version of '%s' which is too high. min_engine_version is newer than the server build

Common Issues

  • Pack uploaded, nothing happened. It is not listed in the world's world_behavior_packs.json or world_resource_packs.json. Uploading alone never activates anything.
  • The world loads but the add-on is missing, and there is no error. The pack_id or version in the world file does not match the manifest. The server logs "Configured pack ... was not found and was ignored" and moves on.
  • Custom mob is invisible or an untextured shape. The behaviour pack loaded and its resource pack did not. Check the dependencies UUID, and check the resource pack is installed too.
  • Works on your own device, not on the server. You installed it into the client's development_behavior_packs folder, which is a client-only path. The server reads behavior_packs/.
  • Two packs, one wins. Pack stacking — the later entry overrides the earlier one. Reorder them, or set priority.
  • Players are never prompted for the resource pack. It is not in world_resource_packs.json, or it is optional and they declined. texturepack-required=true makes it mandatory.
  • Nothing in the console when a pack fails. Content logging is off by default. Set content-log-file-enabled=true and content-log-console-output-enabled=true, then restart.

Sources


Made with 💜 by GameServerKings

Need a Minecraft server?

Deploy an instantly-provisioned Minecraft server on high-clock hardware — DDoS protected, no contracts, cancel anytime.

From $4.80 /month