Quick answer: Your exported build is missing the compiled shared library. Add the .dll/.so/.dylib to your export’s Include Filter, verify the .gdextension file has the correct platform key and path, and make sure you compiled with the template_release (or template_debug) target, not the editor target.

Your GDExtension loads perfectly inside the Godot editor. Classes appear in the node menu, everything works. You export the game, run the binary, and the extension is gone — custom classes are missing, or the game crashes on startup with a library-not-found error. This is one of the most disorienting export bugs because the editor gives you zero warning that the export will fail.

The Symptom

After exporting, you observe one or more of the following:

What Causes This

There are three distinct failure points, and they often stack:

1. The shared library is not included in the export. Godot’s export system only auto-includes files that are imported as resources. Native libraries (.dll, .so, .dylib) are not imported — they must be included explicitly via the export filter or by ensuring they are referenced in the .gdextension file under res://.

2. The .gdextension file has wrong platform keys or paths. Each platform has a specific key format. If the key is wrong (e.g. windows.64 instead of windows.x86_64) or the path does not match where the library actually is, the extension will silently fail to load.

3. The library was compiled for the editor target, not the export template target. Libraries compiled with target=editor are only loaded by editor builds. Export templates require target=template_debug or target=template_release.

The Fix: Correct .gdextension File

The .gdextension file is the manifest that tells Godot where to find the native library for each platform. The [libraries] section maps platform feature tags to library paths:

# my_extension.gdextension
[configuration]
entry_symbol = "my_extension_init"
compatibility_minimum = "4.1"

[libraries]
# Windows 64-bit
windows.x86_64.debug   = "res://bin/my_extension.windows.template_debug.x86_64.dll"
windows.x86_64.release = "res://bin/my_extension.windows.template_release.x86_64.dll"

# Linux 64-bit
linux.x86_64.debug   = "res://bin/my_extension.linux.template_debug.x86_64.so"
linux.x86_64.release = "res://bin/my_extension.linux.template_release.x86_64.so"

# macOS (universal .framework bundle)
macos.debug   = "res://bin/my_extension.macos.template_debug.framework"
macos.release = "res://bin/my_extension.macos.template_release.framework"

[icons]
MyExtensionClass = "res://addons/my_extension/icon.svg"

The platform tag format is <os>.<arch>.debug or <os>.<arch>.release. Valid OS values are windows, linux, macos, android, ios, web. Valid arch values are x86_64, x86_32, arm64, arm32, wasm32. macOS uses a .framework directory, not a flat .dylib, for universal builds.

The Fix: Include the Library in the Export

Open Project > Export, select your export preset, and go to the Resources tab. In the Filters to export non-resource files/folders field (also shown as “Include Filter”), add a glob pattern that matches your library files:

# Include Filter examples (one per line in the Export dialog):
# bin/*.dll
# bin/*.so
# bin/*.framework

# Or include the whole bin directory:
# bin/*

Files under res:// that are referenced in the .gdextension file are not automatically included by the exporter the way GDScript or scene files are. You must explicitly tell the exporter to pack them. This is the single most common reason a working editor extension vanishes in an exported build.

The Fix: Build for the Correct Target

If you use SCons (the standard GDExtension build system via godot-cpp), you must compile separate libraries for the editor, debug template, and release template. The editor binary will only load editor-target libraries:

# Build for editor (used by Godot editor only):
# scons target=editor

# Build for exported debug builds:
# scons target=template_debug

# Build for exported release builds (no debug symbols, optimized):
# scons target=template_release

# Cross-compile for a different platform (example: Windows from Linux):
# scons target=template_release platform=windows

A clean workflow: build all three targets, name them descriptively to match your .gdextension paths, and commit all three to res://bin/. The export system picks the right one based on the feature tags.

Initialization Level and Registration

The initialization level in your C++ entry point controls when your extension’s classes become available. Most extensions that register custom node types must use INITIALIZATION_LEVEL_SCENE, not INITIALIZATION_LEVEL_CORE. Registering at the wrong level can cause classes to be unavailable when scenes load:

// C++ entry point (my_extension.cpp)
// INITIALIZATION_LEVEL_CORE  — before scene system; for low-level utilities
// INITIALIZATION_LEVEL_SCENE — scene system ready; use for custom nodes
// INITIALIZATION_LEVEL_EDITOR — editor only; for editor plugins

void initialize_my_extension(ModuleInitializationLevel p_level) {
    if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
        return;
    }
    ClassDB::register_class<MyCustomNode>();
}

extern "C" {
GDExtensionBool GDE_EXPORT my_extension_init(
    GDExtensionInterfaceGetProcAddress p_get_proc_address,
    const GDExtensionClassLibraryPtr p_library,
    GDExtensionInitialization *r_initialization
) {
    GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
    init_obj.register_initializer(initialize_my_extension);
    init_obj.register_terminator(uninitialize_my_extension);
    init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
    return init_obj.init();
}
}

Related Issues

See also: Fix: Custom Fonts and Assets Not Loading in Godot Export.

See also: Common Godot Export Bugs and How to Fix Them.

Build for the right target, include the library in the export filter, and keep your platform keys exact — GDExtension has no tolerance for guesses.