docker/cli · error
plugin SchemaVersion version cannot be empty
Error message
plugin SchemaVersion version cannot be empty
What it means
validateSchemaVersion (cli-plugins/manager/plugin.go:138) checks a candidate plugin's metadata. The SchemaVersion field is mandatory; if it is the zero value (empty string) the function returns errors.New("plugin SchemaVersion version cannot be empty") at line 143. This error is wrapped into Plugin.Err during newPlugin, marking the plugin as failed but still returning the Plugin (non-fatal to the CLI as a whole).
Solutions
- Ensure the plugin's metadata output includes "SchemaVersion": "0.1.0" (or any <2.0.0 semver as accepted by validateSchemaVersion).
- Run '<plugin-path> <plugin-name> docker-cli-plugin-metadata' manually and inspect the JSON to confirm the field is present and non-empty.
- Also provide the required Vendor field (checked afterwards at line 124) to avoid the next validation error.
- Update to a current plugin scaffold/template so all required metadata fields are emitted.
Example fix
// before — plugin metadata
{"SchemaVersion":"","Vendor":""}
// after
{"SchemaVersion":"0.1.0","Vendor":"example.com","Name":"myplugin"} Defensive patterns
Strategy: validation
Validate before calling
// Validate a candidate plugin's metadata before registering it:
var meta metadata.Metadata
if err := json.Unmarshal(raw, &meta); err != nil { return err }
if meta.SchemaVersion == "" { return errors.New("metadata missing SchemaVersion") }
// then also confirm Vendor is set Type guard
// newPlugin sets Plugin.Err (a *pluginError) instead of returning a hard error;
// callers check p.Err != nil and the plugin is listed but not invoked.
func isValidPlugin(p manager.Plugin) bool { return p.Err == nil } Try / catch
// Listing plugins already tolerates this: it surfaces the plugin with an error rather than aborting.
// If you enumerate plugins, inspect .Err and skip:
for _, p := range plugins { if p.Err != nil { log.Println("skipping", p.Name, p.Err); continue } } Prevention
- Always emit SchemaVersion (e.g. "0.1.0") and Vendor in plugin metadata.
- Run the metadata subcommand locally and pipe through jq to confirm fields before distributing.
- Pin to a plugin template/scaffold that already includes required metadata.
- Keep SchemaVersion < 2.0.0; older CLIs (<28.4.1) only accept "0.1.0".
When it happens
Trigger: A plugin binary whose metadata JSON omits the SchemaVersion field entirely, or sets it to "". The metadata is fetched by running the plugin with the metadata subcommand; a plugin that returns {} or {"SchemaVersion":""} triggers it.
Common situations: Hand-written or in-development plugins that have not populated the SchemaVersion metadata; plugins built against a very old/unknown template that lacks the field; corrupt metadata output.
Related errors
- failed to parse hook template
- unexpected hook response type
- plugin SchemaVersion
- error: trust data missing for remote repository
- conflicting options: cannot specify both --host and…
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/2399e081dd0eae0b.
Report an issue: GitHub.
Appendix: source
Thrown at cli-plugins/manager/plugin.go:143
p.Err = newPluginError("plugin metadata does not define a vendor")
return p, nil
}
return p, nil
}
// validateSchemaVersion validates if the plugin's schemaVersion is supported.
//
// The current schema-version is "0.1.0", but we don't want to break compatibility
// until v2.0.0 of the schema version. Check for the major version to be < 2.0.0.
//
// Note that CLI versions before 28.4.1 may not support these versions as they were
// hard-coded to only accept "0.1.0".
func validateSchemaVersion(version string) error {
if version == "0.1.0" {
return nil
}
if version == "" {
return errors.New("plugin SchemaVersion version cannot be empty")
}
major, _, ok := strings.Cut(version, ".")
majorVersion, err := strconv.Atoi(major)
if !ok || err != nil {
return fmt.Errorf("plugin SchemaVersion %q has wrong format: must be <major>.<minor>.<patch>", version)
}
if majorVersion > 1 {
return fmt.Errorf("plugin SchemaVersion %q is not supported: must be lower than 2.0.0", version)
}
return nil
}
// RunHook executes the plugin's hooks command
// and returns its unprocessed output.
func (p *Plugin) RunHook(ctx context.Context, hookData hooks.Request) ([]byte, error) {
hDataBytes, err := json.Marshal(hookData)
if err != nil {
return nil, wrapAsPluginError(err, "failed to marshall hook data")View on GitHub (pinned to 4f84911bfe)