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
- Align versions: run a client (binary/library) matching the daemon's version.
- Rebuild or reinstall the ipfs binary/tooling after upgrading the daemon.
- Check both versions (`ipfs version --all` locally and remotely); the error body shows the exact mismatch.
- 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
- Check the daemon version via the version endpoint before issuing commands
- Avoid pointing one binary at daemons of a different release; deploy binary and daemon together
- In CI, install the ipfs binary from the same source revision as the daemon under test
- Parse the "(a != b)" body to log which side needs upgrading
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
- api version mismatch
- unexpected redirect
- Kubo RPC Access Denied: Please provide a valid authorization
- ipfs api address could not be found
- unsupported file type '%s'
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/54a879fd81069f8d.
Report an issue: GitHub.