influxdata/influxdb · error · ProcessingEngineError::PluginError
Plugin not found: {}
Error message
Plugin not found: {} What it means
update_plugin() locates the plugin to update by iterating every database schema's processing_engine_triggers and matching trigger_name against the requested plugin_name; it rewrites the found plugin's __init__.py. If no trigger matches, it returns ProcessingEngineError::PluginError('Plugin not found: {plugin_name}'). Matching is exact (case-sensitive) on the trigger name, not the file name.
Source
Thrown at influxdb3_processing_engine/src/lib.rs:1120
async_fs::write(&plugin_path, content).await.map_err(|e| {
ProcessingEngineError::PluginError(plugins::PluginError::ReadPluginError(e))
})?;
return Ok(db_schema.name.to_string());
}
// For multi-file plugins (directories), update __init__.py by default
let init_file = plugin_path.join(INIT_PY);
async_fs::write(&init_file, content).await.map_err(|e| {
ProcessingEngineError::PluginError(plugins::PluginError::ReadPluginError(e))
})?;
return Ok(db_schema.name.to_string());
}
}
Err(ProcessingEngineError::PluginError(
plugins::PluginError::AnyhowError(anyhow::anyhow!("Plugin not found: {}", plugin_name)),
))
}
/// Replace an entire plugin directory atomically with new files.
pub async fn replace_plugin_directory(
self: &Arc<Self>,
plugin_name: &str,
files: Vec<(String, String)>, // Vec of (relative_path, content)
) -> Result<String, ProcessingEngineError> {
if self.environment_manager.plugin_dir_only {
return Err(ProcessingEngineError::PluginError(
PluginError::PluginInstallationDisabled,
));
}
// Find the trigger to get the plugin filename
let (db_name, plugin_filename) = {
let mut result = None;View on GitHub (pinned to d28e26e048)
Solutions
- List the installed plugin files via the HTTP endpoints (/api/v3/plugins/files, /api/v3/plugins/directory) and check the trigger names in your create-trigger command history
- Use the exact, case-sensitive trigger name the trigger was created with
- If the plugin genuinely does not exist, create it first, then update
Example fix
# before: trigger was created as 'my-scheduler' PUT /api/v3/plugins/files?name=MyScheduler # -> Plugin not found: MyScheduler # after PUT /api/v3/plugins/files?name=my-scheduler
Defensive patterns
Strategy: validation
Validate before calling
# confirm the plugin file exists before updating it
curl -sf "${INFLUXDB3_HOST_URL}/api/v3/plugins/files" \
| grep -q "\"${PLUGIN_NAME}\"" \
|| { echo "plugin '${PLUGIN_NAME}' not installed" >&2; exit 1; } Prevention
- Keep a manifest of installed trigger names and drive updates from it
- Trigger-name matching is exact and case-sensitive — copy names from the create-trigger command
- Create the plugin/trigger before scripting updates against it
When it happens
Trigger: Calling the plugin update endpoint/method with a name that does not exactly equal an installed trigger's name — a typo, different casing, or using the plugin filename (e.g. 'my_plugin.py') where the trigger name (e.g. 'my-plugin') is required. Also updating a plugin that was never created.
Common situations: Renaming plugins after creation; automating update flows where the name comes from a config that drifted from the installed trigger name; environments with several databases where the operator assumed a global name.
Related errors
- No plugin directory configured
- Failed to rename temp directory to target
- request trigger execution cancelled
- invalid database name: {db_name}
- unsupported Arrow type for Python conversion: {:?}. Supporte
AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16).
Data as JSON: /api/errors/07eeb215d75bfce1.
Report an issue: GitHub.