Summary
My JUCE 8.0.12 VST3 plugin (Windows) scans successfully in FL Studio and shows an “OK” status, but fails the moment it is actually loaded into a project with a popup “failed to load for an unknown reason, make sure it was installed correctly” and the plugin window drawing “This plugin failed to load.”
The same binary loads and runs perfectly in:
pluginval (strictness 10, all tests pass)
Ableton Live 12
Audacity
FL Studio 12
FL Studio 24 on my personal dev machine
It fails at instantiation in:
FL Studio 20, 25, and 26 on multiple clean machines, and in a fresh Windows 11 VM (reproduced reliably)
I have added file-based trace logging to my AudioProcessor constructor and createEditor(). On every host where it works, the trace fires normally. In FL 20/25/26 on clean machines, no trace line is ever written - not even the first line of the processor constructor, and not during scanning either. So FL is rejecting the plugin before my code runs at all, at the VST3 module/factory stage.
Key detail
It works in FL (all versions incl. 26) only on my personal dev machine, which happens to be a modified/debloated Windows install. On clean, stock Windows 11 it fails in FL 20/25/26. So my working case appears to be the outlier, not the failing ones. FL 12 loads it fine even on the clean machines (older FL hosting path).
What I have already ruled out
VC++ runtime: statically linked (CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"). dumpbin /dependents shows no vcruntime/msvcp imports.
Missing DLLs: Dependencies (lucasg) shows everything resolving to system32; the DLL image loads (confirmed via Procmon on a failing machine - image load succeeds, then FL abandons it).
COMCTL32 v6: embedded an isolation-aware manifest (verified present in the binary via mt.exe). No change.
Direct2D: forced the GDI renderer at runtime via peer->setCurrentRenderingEngine(0) in parentHierarchyChanged(). No change. (Also confirmed the JUCE 8 render path has no JUCE_DIRECT2D preprocessor toggle.)
moduleinfo.json: CIDs decode correctly against my plugin/manufacturer codes; deleting the file entirely changes nothing.
Manufacturer code: saw the thread about lowercase manufacturer codes breaking FL; mine was YNme, changed to Augr (uppercase-first). No change.
Stale FL plugin DB / cache: reproduced from a clean FL install and a clean VM snapshot, fresh scans each time.
Build config (relevant excerpt)
JUCE 8.0.12, CMake, Visual Studio 2022, C++17
Windows VST3 built and also copied into C:\Program Files\Common Files\VST3 (both via COPY_PLUGIN_AFTER_BUILD and a manual post-build copy_directory from $<TARGET_FILE_DIR>/VST3)
I do not currently set VST3_AUTO_MANIFEST.
Questions
What exactly does FL query at the VST3 factory stage that would cause a clean rejection before component instantiation, while pluginval/Ableton/Audacity/older FL accept the same binary?
Could my having two copy mechanisms (COPY_PLUGIN_AFTER_BUILD plus a manual copy_directory of $<TARGET_FILE_DIR>/VST3) be shipping a bundle that skipped JUCE’s post-build finalization/manifest step? What is the correct single source directory to distribute?
Is VST3_AUTO_MANIFEST relevant here, and should it be set?
Is there anything specific to FL Studio 20+ VST3 hosting (vs FL 12) that a JUCE 8.0.12 plugin must satisfy at the factory/module level?
Happy to provide the full CMakeLists, Procmon logs, and the trace instrumentation. I have a 100% reproducible clean-VM repro and can test builds quickly.
Thanks in advance.
If you weren’t aware, AI-generated content should not be posted on the JUCE forum:
I’ll let this post stand, since you may not have been aware of this rule.
It’s difficult to guess at the cause of this problem. JUCE 8.0.12 is a bit old now, so perhaps you could try updating to JUCE 9 (develop) to see whether the problem has already been fixed there.
What exactly does FL query at the VST3 factory stage that would cause a clean rejection before component instantiation, while pluginval/Ableton/Audacity/older FL accept the same binary?
The best way to answer this is to attach a debugger to FL Studio and to stick some breakpoints in the methods of JUCE’s IPluginFactory implementation to see which functions are being called and how they’re returning.
This would depend on the order that the steps run. Normally you shouldn’t need to write your own copy_directory step, that sounds a bit suspicious.
A standard JUCE VST3 build using CMake will produce a directory with the extension ‘.vst3’ that contains the built plugin and the moduleinfo.json. The directory layout is explained here. Normally, it is the directory with the .vst3 extension that should be distributed.
Is VST3_AUTO_MANIFEST relevant here, and should it be set?
You said that you checked the UIDs in the manifest, and that you get the same results without the manifest, so I suspect this is not relevant. Using the default setting for VST3_AUTO_MANIFEST (i.e. not mentioning it in the CMakeLists.txt at all) should do the right thing for the vast majority of plugins.
Thank you very much for the exception. These are very valuable pieces of information and I appreciate such a timely response. Your points were helpful and the issue was naturally a combination of them as well as my MIDI rules conflicting in my header and cmakelists. FL seems to be picky about having both explicitly set.