hasura/graphql-engine · error

can't create symbolic link, source binary (%q) cannot be fou

Error message

can't create symbolic link, source binary (%q) cannot be found in extracted archive: %w

What it means

After clearing the old symlink, createOrUpdateLink stats the extracted binary path to confirm it exists. If os.Stat returns fs.ErrNotExist, the manifest's bin path does not point at a file inside the extracted archive, and linking is aborted with this error naming the missing binary path.

Source

Thrown at cli/plugins/util.go:190

	goos := runtime.GOOS

	return goos == "windows"
}

func createOrUpdateLink(binDir, binary, plugin string) error {
	var op errors.Op = "plugins.createOrUpdateLink"

	dst := filepath.Join(binDir, PluginNameToBin(plugin, IsWindows()))

	err := removeLink(dst)
	if err != nil {
		return errors.E(op, fmt.Errorf("failed to remove old symlink: %w", err))
	}

	if _, err := os.Stat(binary); stderrors.Is(err, fs.ErrNotExist) {
		return errors.E(
			op,
			fmt.Errorf(
				"can't create symbolic link, source binary (%q) cannot be found in extracted archive: %w",
				binary,
				err,
			),
		)
	}

	// Create new
	err = os.Symlink(binary, dst)
	if err != nil {
		if IsWindows() {
			// If cloning the symlink fails on Windows because the user
			// does not have the required privileges, ignore the error and
			// fall back to copying the file contents.
			//
			// ERROR_PRIVILEGE_NOT_HELD is 1314 (0x522):
			// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx
			var lerr *os.LinkError

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Download and extract the archive manually and note the real binary path relative to the extraction root.
  2. Update the platform's "bin" field to that exact path (include the .exe suffix for windows platforms).
  3. Reinstall; the link will then be recreated against the correct binary.

Example fix

// before
"bin": "myplugin"        // archive actually extracts to bin/myplugin

// after
"bin": "bin/myplugin"
Defensive patterns

Strategy: validation

Validate before calling

want := filepath.Join(extractDir, filepath.FromSlash(pl.Bin))
if _, err := os.Stat(want); os.IsNotExist(err) {
	return fmt.Errorf("manifest bin %q not present after extract; listing: %v", pl.Bin, listArchiveEntries())
}

Try / catch

if err := plugins.Install(...); err != nil {
	if strings.Contains(err.Error(), "cannot be found in extracted archive") {
		// extract manually, locate the real binary, fix manifest "bin", reinstall
	}
}

Prevention

When it happens

Trigger: installPlugin where the platform manifest's "bin" value (e.g. "bin/mytool") does not match any file in the extracted archive — wrong relative path, different binary name in the release, or the archive has a top-level directory the path omits.

Common situations: Release archives renamed the binary (myplugin-v2.0-linux-amd64 vs myplugin); manifest bin path missing the archive's top-level folder; .exe suffix issues on windows platforms entries.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/ff8f4b4c6edc3cf9. Report an issue: GitHub.