{"record":{"id":"567aca77a466549f","repo":"hashicorp/nomad","slug":"plugin-not-executable","errorCode":null,"errorMessage":"plugin not executable","messagePattern":"plugin not executable","errorType":"exception","errorClass":"ErrPluginNotExecutable","httpStatus":null,"severity":"error","filePath":"client/commonplugins/commonplugins.go","lineNumber":19,"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) {\n\tvar errBuf bytes.Buffer","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/commonplugins/commonplugins.go#L1-L37","documentation":"ErrPluginNotExecutable is a sentinel error returned when a Nomad external/common plugin binary exists but is not executable (helper.IsExecutable check fails). It is wrapped with the plugin name by the same constructors as ErrPluginNotExists.","triggerScenarios":"NewExternalSecretsPlugin, NewHostVolumePluginExternal, or TestNewHostVolumePluginExternal locate the plugin file but helper.IsExecutable(f) returns false — i.e. no execute bit set or file is not a regular executable file.","commonSituations":"Plugin binary downloaded/tar-extracted without preserving permissions; chmod +x forgotten in provisioning scripts; umask stripped execute bit; plugin replaced by a data file or script lacking +x; non-root nomad user cannot execute due to permissions on parent dirs.","solutions":["chmod +x the plugin binary on the client host","Re-install the plugin preserving executable permissions (e.g. tar --preserve-permissions, install -m 0755)","Confirm the file is a real executable (file <path>) and not a truncated/corrupt download","Ensure the nomad user can traverse the plugin directory and execute the file"],"exampleFix":"// before (shell provisioning)\nwget -O /opt/nomad/plugins/csi-plugin https://example.com/csi-plugin\n// after\nwget -O /opt/nomad/plugins/csi-plugin https://example.com/csi-plugin && chmod 0755 /opt/nomad/plugins/csi-plugin","handlingStrategy":"validation","validationCode":"// before configuring the plugin, verify it is executable\ninfo, err := os.Stat(p)\nif err != nil {\n    return err\n}\nif info.Mode()&0111 == 0 {\n    return fmt.Errorf(\"plugin %q is not executable; run chmod +x\", p)\n}","typeGuard":"func pluginExecutable(path string) bool {\n    info, err := os.Stat(path)\n    return err == nil && info.Mode()&0111 != 0\n}","tryCatchPattern":"plugin, err := NewHostVolumePluginExternal(cfg)\nif err != nil {\n    if errors.Is(err, ErrPluginNotExecutable) {\n        if execErr := os.Chmod(pluginPath, 0o755); execErr != nil {\n            return execErr\n        }\n        return retryNewPlugin(cfg)\n    }\n    return err\n}","preventionTips":["Always chmod 0755 plugin binaries during provisioning","Extract archives with permission preservation (tar -p / umask 022)","Verify executability in CI/CD images that ship plugins","Ensure the nomad service user can execute the binary (ownership + dir traversal)"],"tags":["nomad","plugin","permissions","filesystem"],"backgroundTag":"permission-denied","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"}