go 41 lines · 1 tab

Config parsing with env defaults and strict validation

Leah Thompson Jan 2026
1 tab
package config

import (
  "errors"
  "os"
  "strconv"
  "time"
)

type Config struct {
  Port        int
  DatabaseURL string
  HTTPTimeout time.Duration
}

func Load() (Config, error) {
  port := 8080
  if v := os.Getenv("PORT"); v != "" {
    p, err := strconv.Atoi(v)
    if err != nil {
      return Config{}, err
    }
    port = p
  }

  db := os.Getenv("DATABASE_URL")
  if db == "" {
    return Config{}, errors.New("DATABASE_URL is required")
  }

  timeout := 2 * time.Second
  if v := os.Getenv("HTTP_TIMEOUT"); v != "" {
    d, err := time.ParseDuration(v)
    if err != nil {
      return Config{}, err
    }
    timeout = d
  }

  return Config{Port: port, DatabaseURL: db, HTTPTimeout: timeout}, nil
}
1 file · go Explain with highlit

Config bugs are some of the most expensive production incidents because they vary by environment and can be hard to reproduce. I keep configuration in a typed struct, load it from environment variables, and validate it before the server starts. The validation step is the important part: fail fast with a clear message rather than booting with 0 values that cause weird behavior later. I also parse durations with time.ParseDuration so settings like HTTP_TIMEOUT=2s remain readable. When secrets are involved, I avoid printing them in logs and only log which required keys are missing. This snippet shows a pragmatic “no dependencies” approach, but the discipline scales to envconfig or a full config system later. Good config hygiene makes deploys boring.


Related snips

Share this code

Here's the card — post it anywhere.

Config parsing with env defaults and strict validation — share card
Link copied