Bug report
Expected behavior and actual behavior
When all requested plugins are pinned to exact versions and already installed in $NXF_HOME/plugins/, Nextflow should start them from the local directory without requiring network access.
Instead, Nextflow unconditionally calls the plugin registry API at startup (PluginsFacade.groovy:415), and if the registry is unreachable, the run aborts with a PluginRuntimeException even though the fetched metadata is never used.
This affects users in airlocked/firewalled environments who pre-install plugins into their container images. They have done everything right (pinned versions, pre-populated the plugins directory), but Nextflow still requires network access to a service whose response it will discard.
Steps to reproduce the problem
- Install a plugin locally:
curl -L -o nf-schema-2.4.2.zip \
"https://registry.nextflow.io/api/v1/plugins/nf-schema/2.4.2/download/nf-schema-2.4.2.zip"
unzip nf-schema-2.4.2.zip -d $NXF_HOME/plugins/
- Create a workflow that pins the plugin version:
plugins {
id 'nf-schema@2.4.2'
}
workflow {
log.info "Plugin loaded successfully"
}
- Block access to
registry.nextflow.io (e.g. via firewall rule or /etc/hosts) and run:
- Nextflow fails at the metadata prefetch, before it ever checks whether the plugin is already installed locally.
Note: NXF_OFFLINE=true works around the plugin issue but also blocks remote pipeline cloning (CmdRun.groovy:620-621), making it unusable for environments that need to fetch pipelines from a Git server (e.g. Seqera Platform pulling from GitLab).
Program output
Unable to connect to https://registry.nextflow.io/api/v1/plugins/dependencies?plugins=nf-schema%402.4.2&nextflowVersion=25.10.2 - cause: <connection error>
Environment
- Nextflow version: 25.10.2+ (any version using the registry-based plugin system)
- Java version: any
- Operating system: any
- Bash version: any
Additional context
The root cause is in the startup sequence in PluginsFacade.start():
// prefetch the plugins meta
updater.prefetchMetadata(startable) // <-- always makes HTTP call, throws on failure
// finally start the plugins
for( PluginRef plugin : startable ) {
updater.prepareAndStart(plugin.id, plugin.version) // <-- would succeed from local dir
}
In PluginUpdater.load0(), when a plugin has an exact version and is already installed, no metadata is consulted:
- Line 351-359: version resolution is skipped (exact semver provided)
- Line 372-375: directory exists, download is skipped
- Line 386-406: transitive deps are read from the plugin's own MANIFEST, not registry metadata
The prefetched metadata is write-only for this code path.
A minimal fix would be to make the prefetchMetadata failure non-fatal (log a warning instead of throwing), so that the actual failure surfaces later only if something genuinely needs the metadata (version resolution for unpinned plugins, download URLs for missing plugins). If nothing needs it, the run succeeds.
See also #6988, which describes a related problem with NXF_OFFLINE being too coarse-grained.
Bug report
Expected behavior and actual behavior
When all requested plugins are pinned to exact versions and already installed in
$NXF_HOME/plugins/, Nextflow should start them from the local directory without requiring network access.Instead, Nextflow unconditionally calls the plugin registry API at startup (
PluginsFacade.groovy:415), and if the registry is unreachable, the run aborts with aPluginRuntimeExceptioneven though the fetched metadata is never used.This affects users in airlocked/firewalled environments who pre-install plugins into their container images. They have done everything right (pinned versions, pre-populated the plugins directory), but Nextflow still requires network access to a service whose response it will discard.
Steps to reproduce the problem
plugins { id 'nf-schema@2.4.2' } workflow { log.info "Plugin loaded successfully" }registry.nextflow.io(e.g. via firewall rule or/etc/hosts) and run:Note:
NXF_OFFLINE=trueworks around the plugin issue but also blocks remote pipeline cloning (CmdRun.groovy:620-621), making it unusable for environments that need to fetch pipelines from a Git server (e.g. Seqera Platform pulling from GitLab).Program output
Environment
Additional context
The root cause is in the startup sequence in
PluginsFacade.start():In
PluginUpdater.load0(), when a plugin has an exact version and is already installed, no metadata is consulted:The prefetched metadata is write-only for this code path.
A minimal fix would be to make the
prefetchMetadatafailure non-fatal (log a warning instead of throwing), so that the actual failure surfaces later only if something genuinely needs the metadata (version resolution for unpinned plugins, download URLs for missing plugins). If nothing needs it, the run succeeds.See also #6988, which describes a related problem with
NXF_OFFLINEbeing too coarse-grained.