argoproj/argo-workflows · error

plugin is directory check failed

Error message

plugin %s is directory check failed: %s

What it means

This error wraps an in-band failure reported by the artifact plugin itself: the gRPC call succeeded, but the plugin set resp.Error to a non-empty message. Argo surfaces the plugin's own error text prefixed with the plugin name, so the root cause description comes from the plugin implementation, not Argo.

Solutions

  1. Read the trailing %s text — it is the plugin's own error message describing the real failure
  2. Check the plugin's configuration (ConfigMap-based plugin config) for storage credentials/endpoint mistakes
  3. Check the plugin's server logs for the corresponding request failure
  4. Validate the artifact definition (key/path format) against what the plugin expects
  5. Update or fix the plugin if its handler incorrectly flags valid requests
Defensive patterns

Strategy: try-catch

Try / catch

ok, err := driver.IsDirectory(ctx, artifact)
if err != nil {
    // resp.Error text is embedded after the prefix
    if strings.Contains(err.Error(), "is directory check failed") {
        log.Error("plugin reported failure; inspect plugin logs and its backend storage config", "err", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Driver.IsDirectory on a plugin artifact where the plugin's server-side IsDirectory handler returned an error payload in the response (resp.Error != "") — e.g. the plugin failed to authenticate to its backend storage or rejected the artifact reference.

Common situations: Plugin cannot access its backing storage (bad credentials in plugin config); artifact reference invalid for the plugin's expected schema; plugin-side bug or unsupported storage backend; plugin reporting backend 403/404 conditions as errors.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/370da46de5797a67. Report an issue: GitHub.

Appendix: source

Thrown at workflow/artifacts/plugin/plugin.go:366

		return nil, fmt.Errorf("plugin %s list objects failed: %w", d.pluginName, err)
	}
	if resp.Error != "" {
		return nil, fmt.Errorf("plugin %s list objects failed: %s", d.pluginName, resp.Error)
	}
	return resp.Objects, nil
}

// IsDirectory implements ArtifactDriver.IsDirectory by calling the plugin service
func (d *Driver) IsDirectory(ctx context.Context, artifactRef *wfv1.Artifact) (bool, error) {
	grpcArtifact := convertToGRPC(artifactRef)
	resp, err := d.client.IsDirectory(ctx, &artifact.IsDirectoryRequest{
		Artifact: grpcArtifact,
	})
	if err != nil {
		return false, fmt.Errorf("plugin %s is directory check failed: %w", d.pluginName, err)
	}
	if resp.Error != "" {
		return false, fmt.Errorf("plugin %s is directory check failed: %s", d.pluginName, resp.Error)
	}
	return resp.IsDirectory, nil
}

// convertToGRPC converts v1alpha1.Artifact to gRPC Artifact
func convertToGRPC(a *wfv1.Artifact) *artifact.Artifact {
	if a == nil {
		return nil
	}

	grpcArtifact := &artifact.Artifact{
		Name:           a.Name,
		Path:           a.Path,
		From:           a.From,
		Optional:       a.Optional,
		SubPath:        a.SubPath,
		RecurseMode:    a.RecurseMode,
		FromExpression: a.FromExpression,

View on GitHub (pinned to 35bff19146)