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.
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.htmlmanual, themanifest.jsonfiles of the vanilla and chemistry packs it ships, theen_US.langmessage catalogue insideresource_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.
.mcaddonand.mcpackare ZIP files with a different extensionThe 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
.mcpackis one pack; an.mcaddonis 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]
}
]
} 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 standardxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxhexadecimal 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.typeon a module —resources,data,script, orworld_template.
Version numbers are arrays on Bedrock, not integers
Java's
pack.mcmetacarries a singlepack_formatnumber (nowmin_formatandmax_format). Bedrock'smanifest.jsoncarries[major, minor, revision]arrays and amin_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.
The Behaviour-Pack-to-Resource-Pack Link
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"
] 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" }
] 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.jsonworlds/<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]
}
] 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:
Extract the
.mcpackor.mcaddonand upload the pack folder tobehavior_packs/orresource_packs/— through the File Manager for something small, over SFTP for a large textured pack.Open the pack's
manifest.jsonand copy theheaderuuidandversion.Add an entry with that
pack_idandversiontoworlds/<level-name>/world_behavior_packs.json, or the resource equivalent. If the file does not exist, create it; an empty one is[].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-enabledandcontent-log-console-output-enabledinserver.propertiesbefore 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 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-packURL key on BedrockJava serves a resource pack from a URL with a SHA-1 hash, using the
resource-pack,resource-pack-sha1andrequire-resource-packkeys. Bedrock has none of those. The pack is stored in or beside the world and sent to the client by the server itself, andtexturepack-requiredis the only related setting. If a guide tells you to paste a pack URL intoserver.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 {
"input_directory": "D:/work/packs_input",
"output_directory": "D:/work/packs_output",
"verbose_logging": false
} 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.jsonorworld_resource_packs.json. Uploading alone never activates anything. - The world loads but the add-on is missing, and there is no error. The
pack_idorversionin 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
dependenciesUUID, 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_packsfolder, which is a client-only path. The server readsbehavior_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=truemakes it mandatory. - Nothing in the console when a pack fails. Content logging is off by default. Set
content-log-file-enabled=trueandcontent-log-console-output-enabled=true, then restart.
Sources
- The
bedrock_server_how_to.htmlmanual, theserver.properties, thebehavior_packs/vanilla,resource_packs/vanillaandchemistrymanifests, theresource_packs/vanilla/texts/en_US.langmessage catalogue and thebedrock_serverbinary, all read from the official Bedrock Dedicated Server archive, version 1.26.44.3 - Microsoft Learn — manifest.json for Behavior/Resource/Skin Packs and World Templates
- Microsoft Learn — Getting Started with Bedrock Dedicated Server
- Microsoft Learn — Pack Optimization Using Dedicated Server
- Microsoft Learn — Comprehensive List of Add-On Pack Contents
- Microsoft Learn — Introduction to Resource Packs and Introduction to Behavior Packs
What to Read Next
- Setting up your Bedrock Minecraft server for first boot, connecting and the platform limitations
- Bedrock server.properties: The Complete Key Reference for
texturepack-required, the content log keys and the script watchdog - Bedrock Allowlist and Permissions for
allowlist.json,permissions.jsonand XUIDs - Bedrock World Management for the world folder these files live in, and for moving a world between machines
- How to Install Datapacks and Resource Packs for the Java Edition side of all of this
- Setting up CrossPlay for Minecraft if you would rather run one Java server that Bedrock clients can join
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