ipfs/kubo · error

%s (%s != %s)

Error message

%s (%s != %s)

What it means

This is the concrete 400 response produced by the version-check middleware: "<errAPIVersionMismatch> (<daemonVersion> != <clientVersion>)". The middleware only applies when the User-Agent looks like a kubo/go-ipfs client and the requested path is not the version endpoint, keeping legacy behavior for version probing. See error 507 for the sentinel.

Source

Thrown at core/corehttp/commands.go:222

}

// CheckVersionOption returns a ServeOption that checks whether the client ipfs version matches. Does nothing when the user agent string does not contain `/kubo/` or `/go-ipfs/`
func CheckVersionOption() ServeOption {
	daemonVersion := version.ApiVersion

	return func(n *core.IpfsNode, l net.Listener, parent *http.ServeMux) (*http.ServeMux, error) {
		mux := http.NewServeMux()
		parent.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			if strings.HasPrefix(r.URL.Path, APIPath) {
				cmdqry := r.URL.Path[len(APIPath):]
				pth := strings.Split(cmdqry, "/")

				// backwards compatibility to previous version check
				if len(pth) >= 2 && pth[1] != "version" {
					clientVersion := r.UserAgent()
					// skips check if client is not kubo (go-ipfs)
					if (strings.Contains(clientVersion, "/go-ipfs/") || strings.Contains(clientVersion, "/kubo/")) && daemonVersion != clientVersion {
						http.Error(w, fmt.Sprintf("%s (%s != %s)", errAPIVersionMismatch, daemonVersion, clientVersion), http.StatusBadRequest)
						return
					}
				}
			}

			mux.ServeHTTP(w, r)
		})

		return mux, nil
	}
}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Align versions: run a client (binary/library) matching the daemon's version.
  2. Rebuild or reinstall the ipfs binary/tooling after upgrading the daemon.
  3. Check both versions (`ipfs version --all` locally and remotely); the error body shows the exact mismatch.
  4. Point the client at a daemon of its own version instead of a shared one of different vintage.

Example fix

// before
IPFS_API=/ip4/host/tcp/5001 ipfs id  # client v0.25 vs daemon v0.30 -> 400
// after
ipfs version           # v0.30.0
# use/rebuild a v0.30.0 client, then:
IPFS_API=/ip4/host/tcp/5001 ipfs id
Defensive patterns

Strategy: retry

Validate before calling

remote, err := shell.Version()
if err != nil {
	return err
}
if remote != version.ApiVersion { // from your client's kubo module
	return fmt.Errorf("skip daemon %s: client is %s", remote, version.ApiVersion)
}

Try / catch

res, err := shell.Post(ctx, "id", nil, nil)
if err != nil && strings.Contains(err.Error(), "api version mismatch") {
	// fall back to a same-version daemon or surface an upgrade prompt
	return fmt.Errorf("version mismatch with RPC daemon: %w", err)
}

Prevention

When it happens

Trigger: A kubo user-agent HTTP client whose version differs from the daemon requests any /api/v0/ command other than version — e.g. an old `ipfs` binary or Go client pointed at a newer daemon via --api or IPFS_API.

Common situations: Mixed-version clusters and Docker swarms; CI using a stale ipfs binary against a freshly built daemon; users setting IPFS_API to a different machine's daemon after one side upgraded.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/54a879fd81069f8d. Report an issue: GitHub.