Member-only story
Go Env Configuration Done Right
Part of the Go Production Series — a collection of opinionated, battle-tested patterns for building Go services in the real world.
Your service deploys fine in staging. In production, it silently connects to the wrong database because DATABASE_URL was never set — it just defaulted to an empty string and sql.Open was happy to accept it. Three hours later, users are writing data to a stale dev instance.
This is the configuration failure mode nobody talks about: not the crash, but the silent misconfiguration. Your service starts, passes health checks, and serves traffic — to the wrong backend.
Getting configuration right in Go means three things: loading it from the right sources, validating it completely at startup, and making it impossible to accidentally log a secret. This article shows you the pattern that does all three.
The Problem With os.Getenv Everywhere
Most Go services start with os.Getenv. It works, which is the problem — it works even when it shouldn't:
// Scattered across handlers, middleware, and main.go
db, _ := sql.Open("postgres", os.Getenv("DATABASE_URL")) // empty string = silent fail
port := os.Getenv("PORT")…







