What this usually means
Applications read configuration from environment-specific sources: environment variables, config files, secret managers, or feature flag services. These values differ between environments by design — staging points to staging databases, production points to production databases. A config mismatch happens when a value in one environment is incorrect, missing, or points to the wrong resource. The code is fine — the instructions it is following are wrong for the environment it is running in.
The first ten minutes \u2014 establish facts before touching code.
- 1List all configuration values the app reads at startup. Compare the values between staging and production.
- 2Check if any config value references an environment-specific hostname or endpoint. Does it point to the right environment?
- 3Check if feature flags are consistent. A flag enabled in staging but disabled in production changes behaviour.
- 4Look for default values in the code. If production does not set a value, the code might use a default that is wrong for production.
- 5Check if the deployment process injects or overrides any config values. CI/CD pipelines sometimes have their own env var overrides.
The specific files, logs, configs, and dashboards that usually own this bug.
- searchEnvironment-specific config files (`.env.staging`, `.env.production`)
- searchDeployment platform environment variable settings (Vercel, Render, Railway, Heroku)
- searchCI/CD pipeline environment variable overrides
- searchFeature flag service dashboard (LaunchDarkly, Flagsmith, custom) — check per-environment flag values
- searchApplication startup logs — does the app log which config values it loaded?
- searchSecret manager (AWS Secrets Manager, Vault) — check per-environment secret values
Practical causes, not theory. These are the things you will actually find.
- warningEnvironment variable has a different value in production than expected
- warningEnvironment variable is missing in production — the code falls back to a default that is wrong for production
- warningFeature flag is enabled in staging but disabled in production (or vice versa)
- warningEndpoint URL points to a staging resource from production code
- warningDatabase connection string references the wrong database or has wrong credentials
- warningConfig file was updated for staging but the change was not propagated to production
- warningA build-time environment variable baked the wrong value into the production bundle
Concrete fix directions. Pick the one that matches your root cause.
- buildAudit all config values across environments with a comparison script — surface any differences
- buildAdd startup validation that checks required config values exist and are in the expected format
- buildUse a config schema (Zod, JSON Schema, type-safe config) that validates all values at startup
- buildLog the loaded config at startup (excluding secrets) so you can verify what the app is actually using
- buildKeep environment-specific config in version control with clear naming (`.env.staging.example`, `.env.production.example`)
A fix you cannot prove is a guess. Close the loop.
- verifiedDeploy to staging first. Run the full test suite against staging. Confirm behaviour matches expectations.
- verifiedCompare config values between staging and production programmatically (a script, not manual diff).
- verifiedRun a smoke test in production that verifies critical config-dependent functionality.
- verifiedAdd a health-check endpoint that validates all required external resources are reachable with the current config.
- verifiedAfter fixing, push a no-op change to staging and production to verify config parity.
Things that make this bug worse or harder to find.
- warningCopying production config to staging or vice versa — they should be similar but environment-specific
- warningUsing hardcoded values that differ between environments instead of reading from config
- warningNot documenting which config values are environment-specific and which are shared
- warningSetting config values in multiple places (env var + config file + CI override) and losing track of precedence
- warningAssuming config parity because 'the code is the same'