sundowndev/phoneinfoga · error
given plugin %s is not valid: %v
Error message
given plugin %s is not valid: %v
What it means
After confirming the path exists, OpenPlugin calls Go's plugin.Open to load the shared object. If the file exists but is not a valid loadable plugin, the underlying plugin.Open error is wrapped as 'given plugin %s is not valid: %v'. This usually means build/incompatibility issues rather than a missing file.
Source
Thrown at lib/remote/scanner.go:38
type Plugin interface {
Lookup(string) (plugin.Symbol, error)
}
type Scanner interface {
Name() string
Description() string
DryRun(number.Number, ScannerOptions) error
Run(number.Number, ScannerOptions) (interface{}, error)
}
func OpenPlugin(path string) error {
if _, err := os.Stat(path); os.IsNotExist(err) {
return fmt.Errorf("given path %s does not exist", path)
}
_, err := plugin.Open(path)
if err != nil {
return fmt.Errorf("given plugin %s is not valid: %v", path, err)
}
return nil
}
View on GitHub (pinned to 55807b05b7)
Solutions
- Read the wrapped %v detail in the message — it states the exact plugin.Open reason
- Rebuild plugin and host with the exact same Go version and flags: 'go build -buildmode=plugin -o scanner.so ./plugin'
- Ensure all shared dependencies are at identical versions in both the host and plugin go.mod (mismatched deps cause 'symbol ... undefined' or 'different versions' errors)
- Confirm the target OS/arch supports Go plugins (Linux; not Windows/macOS reliably) and the file is actually a .so plugin, not a binary
Example fix
// before go build -o scanner.so ./scanner // wrong: not a plugin // after go build -buildmode=plugin -o scanner.so ./scanner # same Go version as host
Defensive patterns
Strategy: try-catch
Validate before calling
info, err := os.Stat(path)
if err != nil || info.IsDir() {
return fmt.Errorf("not a plugin file: %s", path)
}
if filepath.Ext(path) != ".so" {
return fmt.Errorf("expected .so plugin, got %s", path)
} Type guard
func looksLikePlugin(path string) bool {
info, err := os.Stat(path)
return err == nil && !info.IsDir() && filepath.Ext(path) == ".so"
} Try / catch
if err := remote.OpenPlugin(path); err != nil {
if strings.Contains(err.Error(), "is not valid") {
return fmt.Errorf("plugin %s failed to load; rebuild with same Go version and -buildmode=plugin: %v", path, err)
}
return err
} Prevention
- Pin and share the exact same Go toolchain for host and plugin builds (go.mod toolchain directive / CI matrix)
- Always build plugins with -buildmode=plugin
- Keep shared dependency versions identical between host and plugin modules
- Only deploy on Linux; verify with 'file scanner.so' that it is an ELF shared object
When it happens
Trigger: Calling OpenPlugin(path) on a file that exists but fails plugin.Open: file is not a Go plugin (regular binary, ELF without plugin mode), built with a different Go toolchain version, built without -buildmode=plugin, or compiled with mismatched package versions/flags versus the host binary.
Common situations: Plugin and host built with different Go versions (plugin.Open requires identical toolchain); plugin compiled as a normal executable; plugin references dependency versions that don't match the host's go.mod; trying to open a .dylib/.dll on an unsupported OS (Linux-only); stripped or rebuilt .so after host recompile.
Related errors
AI-assisted analysis of sundowndev/phoneinfoga@55807b05b7 (2026-09-03).
Data as JSON: /api/errors/1e23c8ba75a1e9bb.
Report an issue: GitHub.