What is the Options validation pattern, and why validate configuration on startup?

ASP.NET Core Configuration Intermediate 2–3 Yrs3–5 Yrs Conceptual 1 min read

Quick Answer

Bind config to an options class and validate it: builder.Services.AddOptions<SmtpOptions>().Bind(config.GetSection("Smtp")).ValidateDataAnnotations().ValidateOnStart();. ValidateOnStart() makes a missing or invalid setting fail immediately when the app boots, rather than at 2 a.m. the first time that feature runs.

It's binding a config section to a strongly typed options class and then validating it. I chain ValidateDataAnnotations for the attribute rules, or .Validate with a lambda for custom logic, and then ValidateOnStart. That last call is the important one — without it, validation only happens the first time something resolves the options, so a bad connection string or a missing URL doesn't blow up until some feature runs it, often in production. With ValidateOnStart the app refuses to boot, which is exactly what you want.

  • Add [Required], [Range], [Url] to the options class, or use .Validate(o => ..., "message") for custom rules, or implement IValidateOptions<T> for complex/cross-field validation.
  • Without ValidateOnStart, validation runs lazily on first resolve — the error surfaces deep in a request, hard to attribute to config.
  • Fail-fast config validation is part of a good deployment safety net (alongside health checks and smoke tests).