Skip to content

MongoDB driver: gopkg.in/mgo.v2 cannot connect to MongoDB 5.1+ #414

Description

@wilke

Summary

Shock cannot connect to MongoDB 5.1 or newer. gopkg.in/mgo.v2 — still the driver on master as of the March 2026 dependency update — relies on legacy wire protocol opcodes that MongoDB removed in 5.1. The connection is accepted at the TCP level and then immediately dropped during the handshake, so Shock never completes initialisation and never starts its API.

This is not a configuration problem and cannot be worked around by config.

Reproduction

Deploy Shock against MongoDB 7.0.31 with a valid config pointing at the server.

Shock logs (every ~11s, indefinitely):

[INFO] Starting...
[EROR] Could not connect to mongo (host: mongodb:27017) (no reachable servers)

MongoDB logs, same moment — the connection is accepted, not refused:

"msg":"Connection accepted","attr":{"remote":"10.42.0.34:39970", ...}
"c":"ACCESS","msg":"Connection not authenticating","attr":{"client":"10.42.0.34:39970","doc":{}}
"msg":"Connection ended","attr":{"remote":"10.42.0.34:39970", ...}

TCP connectivity and DNS are fine — verified independently with nc -z from inside the Shock container. The failure is purely protocol-level.

Because initialisation never completes, no API routes are registered and nothing binds api-port. The only listener in the container is on :6060, which returns 404 page not found for every path including /node. That makes the failure easy to misdiagnose as a wrong port.

Cause

gopkg.in/mgo.v2 is pinned at v2.0.0-20190816093944-a6b53ec6cb22. The driver has been unmaintained since 2018 (both the original and the globalsign/mgo fork are archived) and predates MongoDB's modern wire protocol. MongoDB 5.1 removed the legacy opcodes it depends on.

The March 2026 dependency sweep (#412, "Update Go dependencies to resolve 20 CVEs") updated x/net, x/text, x/sys, x/oauth2 and yaml.v2, but left the MongoDB driver untouched — understandably, since it is an API-breaking change rather than a version bump.

docker-compose.yml pins mongo:3.6, which is consistent with this: 3.6 is the last release series mgo was designed against. MongoDB 3.6 reached end of life in April 2021.

Impact

  • Shock cannot be deployed against any currently supported MongoDB release. 3.6, 4.0, 4.2 and 4.4 are all EOL; 5.0 is EOL as of October 2024.
  • Anyone deploying Shock into an existing environment must run a dedicated legacy MongoDB alongside whatever else they operate.
  • The symptom is misleading — a healthy-looking container with an empty routing table — so the cost is usually paid in debugging time before the incompatibility is identified.

Suggested fix

Migrate to the official driver, go.mongodb.org/mongo-driver. This is not a drop-in change: session/collection semantics, BSON tag handling and error types all differ, so every file touching the database needs review. From a look at the tree, the surface is shock-server/db/, shock-server/node/, shock-server/user/ and shock-server/auth/.

A smaller interim step, if the port is not on the roadmap: state the MongoDB version requirement prominently in README.md and INSTALL. It is currently only implicit in docker-compose.yml, and a deployer working from the docs has no way to know that a modern MongoDB will fail.

Environment

Shock mgrast/shock:s3.5; master verified to carry the same driver
MongoDB 7.0.31
Platform Kubernetes (k3s v1.34.6), Ubuntu 22.04
Driver gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 (confirmed in go.mod and vendor/modules.txt on master)

Happy to help with the migration or to test a branch against MongoDB 7 — we have an environment set up for exactly this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions