{"record":{"id":"13aa7bbb72597c8c","repo":"hashicorp/nomad","slug":"plugin-not-found","errorCode":null,"errorMessage":"plugin not found","messagePattern":"plugin not found","errorType":"exception","errorClass":"ErrPluginNotExists","httpStatus":null,"severity":"error","filePath":"client/commonplugins/commonplugins.go","lineNumber":18,"sourceCode":"// Copyright IBM Corp. 2015, 2026\n// SPDX-License-Identifier: BUSL-1.1\n\npackage commonplugins\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"os/exec\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/hashicorp/go-version\"\n)\n\nvar (\n\tErrPluginNotExists     error = errors.New(\"plugin not found\")\n\tErrPluginNotExecutable error = errors.New(\"plugin not executable\")\n)\n\ntype CommonPlugin interface {\n\tFingerprint(ctx context.Context) (*PluginFingerprint, error)\n}\n\n// CommonPlugins are expected to respond to 'fingerprint' calls with json that\n// unmarshals to this struct.\ntype PluginFingerprint struct {\n\tVersion *version.Version `json:\"version\"`\n\tType    *string          `json:\"type\"`\n}\n\n// runPlugin is a helper for executing the provided Cmd and capturing stdout/stderr.\n// This helper implements both the soft and hard timeouts defined by the common\n// plugins interface.\nfunc runPlugin(cmd *exec.Cmd, killTimeout time.Duration) (stdout, stderr []byte, err error) {","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/commonplugins/commonplugins.go#L1-L36","documentation":"ErrPluginNotExists is a sentinel error wrapped when a Nomad external/common plugin binary cannot be found on disk. It is returned by constructors for external secrets and host volume plugins after the underlying file open fails with a not-exist error. The wrapper adds the plugin name/path so developers can tell which plugin was missing.","triggerScenarios":"NewExternalSecretsPlugin, NewHostVolumePluginExternal, or TestNewHostVolumePluginExternal is called with a plugin name whose binary does not exist at the expected path (os.Open/ReadDir fails with os.IsNotExist, or os.OpenRoot fails on the plugin dir).","commonSituations":"Typo in plugin name or path in task config; plugin binary not installed/chowned correctly on the client; plugin directory missing after OS image rebuild; case-sensitive path mismatch on Linux.","solutions":["Verify the plugin binary exists at the configured path on the Nomad client host","Fix the plugin name/path in the task or host volume configuration","Install the plugin binary with correct ownership (nomad user) and directory permissions","Check client logs for the exact wrapped path to confirm which file is missing"],"exampleFix":"// before\nplugin = \"cni-secrets\" // binary not installed\n// after\n# ensure /opt/nomad/plugins/cni-secrets exists and config uses full path\nplugin = \"/opt/nomad/plugins/cni-secrets\"","handlingStrategy":"validation","validationCode":"// before configuring the plugin, verify it exists\np := \"/opt/nomad/plugins/cni-secrets\"\nif _, err := os.Stat(p); errors.Is(err, os.ErrNotExist) {\n    return fmt.Errorf(\"plugin %q must be installed first\", p)\n}","typeGuard":"func pluginExists(path string) bool {\n    _, err := os.Stat(path)\n    return err == nil\n}","tryCatchPattern":"plugin, err := NewExternalSecretsPlugin(cfg)\nif err != nil {\n    if errors.Is(err, ErrPluginNotExists) {\n        // install or fix plugin path, then retry\n        return installPlugin(name)\n    }\n    return err\n}","preventionTips":["Provision plugin binaries with config management (Ansible/Packer) so they always exist","Use absolute paths for plugins in configuration","Add a startup health check that stat()s each configured plugin path","Re-verify plugin paths after OS or image upgrades"],"tags":["nomad","plugin","filesystem","config"],"backgroundTag":"file-not-found","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}